为什么 Test::Unit 测试用例启动如此缓慢?

发布于 2024-07-09 08:28:38 字数 783 浏览 15 评论 0原文

>rails -v
Rails 1.2.6

>ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]

当我像这样运行测试装置(测试 Rails 模型类)时,需要 20-30 秒才能开始执行这些测试(显示“已加载套件...”)。 是什么赋予了?

>ruby test\unit\category_test.rb

require File.dirname(__FILE__) + '/../test_helper'

class CategoryTest < Test::Unit::TestCase
    def setup
        Category.delete_all
    end
    def test_create
        obCategoryEntry = Category.new({:name=>'Apparel'})
        assert obCategoryEntry.save, obCategoryEntry.errors.full_messages.join(', ')
        assert_equal 1, Category.count

        assert_not_nil Category.find(:all, :conditions=>"name='Apparel'")
    end
    #.. 1 more test here
end

这是使用没有固定装置的 MySql DB 的 Rails。 这次启动时间超过 30 秒。

>rails -v
Rails 1.2.6

>ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]

When I run a test fixture (that tests a rails model class) like this, it takes 20-30 secs to start executing these tests (show the "Loaded suite..."). What gives?

>ruby test\unit\category_test.rb

require File.dirname(__FILE__) + '/../test_helper'

class CategoryTest < Test::Unit::TestCase
    def setup
        Category.delete_all
    end
    def test_create
        obCategoryEntry = Category.new({:name=>'Apparel'})
        assert obCategoryEntry.save, obCategoryEntry.errors.full_messages.join(', ')
        assert_equal 1, Category.count

        assert_not_nil Category.find(:all, :conditions=>"name='Apparel'")
    end
    #.. 1 more test here
end

This one is Rails using a MySql DB with no fixtures. This time it clocked 30secs+ to startup.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

谎言月老 2024-07-16 08:28:38

看看这个 Rails 测试服务器

引用作者的话:

“每次在 Rails 中运行测试时
应用程序,整个环境是
已加载,包括未加载的库
两次连续运行之间的变化。
这可能需要花费相当多的时间
时间。 如果我们可以加载怎么办
环境一次,并且只重新加载
每次运行前更换零件?
介绍 RailsTestServing。

使用RailsTestServing,运行时间
单个测试文件从 8 个变为
秒数减少到 0.2 秒
电脑。 这是x40的速度
改进。 现在,我不再多想
在 TextMate 中点击 ⌘R 之前。 它
感觉很自由!”

(这是上周 Rails Envy 播客 上的专题报道,我就是在那里找到的。)

Take a look at this Rails Test Server.

A quote from the author:

"Every time you run a test in a Rails
application, the whole environment is
loaded, including libraries that don’t
change between two consecutive runs.
That can take a considerable amount of
time. What if we could load the
environment once, and only reload the
changing parts before each run?
Introducing RailsTestServing.

With RailsTestServing, the run time of
a single test file has gone from 8
seconds down to .2 of a second on my
computer. That’s a x40 speed
improvement. Now, I don’t think twice
before hitting ⌘R in TextMate. It
feels liberating!"

(This was featured on the Rails Envy Podcast this past week which is where I found this.)

怎会甘心 2024-07-16 08:28:38

当开始任何测试时,Rails 首先加载您拥有的任何装置(在测试/装置中)并用它们重新创建数据库。

不过 20-30 秒听起来非常很慢。 在测试运行之前您是否有很多需要加载的装置,或者您的数据库运行缓慢?

When starting any tests, Rails first loads any fixtures you have (in test/fixtures) and recreates the database with them.

20-30 seconds sounds very slow though. Do you have a lot of fixtures that need to be loaded before your tests run, or is your database running slow?

暖风昔人 2024-07-16 08:28:38

Ruby 的 gem 工具遵循路径发现算法,该算法显然对 Windows 不友好(正如我从您的 ruby​​ -v 中看到的那样)。

例如,如果您跟踪使用 加载的 Rails 应用程序,您可以获得清晰的图像。过程周一。 每个(我的意思是每个require 都会开始扫描 Ruby 路径中的所有目录以及所有 gem 目录。 在普通机器上,典型的 require 需要 20 毫秒。 由于 Rails 会产生数百个 require,因此每次启动 Rails 环境时,这 20 毫秒很容易就会达到几秒。 花点时间初始化数据库中的装置,您就会更好地了解为什么需要这么多时间才开始运行测试用例。

也许由于每种文件系统架构和实现(路径缓存等)的原因,这在 Linux 中比在 Windows 中问题要小。 但我不知道你应该责怪谁。 看起来 NTFS 文件系统可以通过更好的路径缓存实现来改进,但是很明显,gem 工具可以实现缓存本身,并且其性能不太依赖于平台。

Ruby's gem tool follows a path discovery algorithm which, apparently, is not Windows (as I see from your ruby -v) friendly.

You can get a clear picture if you trace, for example, a Rails application loading with ProcMon. Every (I really mean every) require starts a scan over all directories in Ruby's path plus all gem directories. A typical require takes 20 ms on an average machine. Since Rails makes hundreds of requires, those 20 ms easily sum up to seconds every time you launch the Rails environment. Take in the time to initialize the fixtures in the database and you get a better idea of why it takes so much time to just begin running the test-cases.

Perhaps because of each file-system architecture and implementation (path caching etc.), this is less of a problem in Linux than in Windows. I don't know who you should blame, though. It looks like the NTFS file-system could be improved with a better path caching implementation, but clearly the gem tool could implement the caching itself and have its performance not so dependent on the platform.

〃温暖了心ぐ 2024-07-16 08:28:38

看起来 Test::Unit 是使用 Ruby 进行单元测试的最简单但也是最慢的方法之一。 替代方案之一是 ZenTest

It seems like Test::Unit is the simplest, but also one of the slowest ways to do unit testing with Ruby. One of alternatives is ZenTest.

梦过后 2024-07-16 08:28:38

测试装置的启动速度并不是特别慢,远不到 20 秒。

(11:39) ~/tmp $ cat test_unit.rb 
require 'test/unit'
class MyTest < Test::Unit::TestCase
  def test_test
    assert_equal("this", "that")
  end
end

(11:39) ~/tmp $ time ruby test_unit.rb 
Loaded suite test_unit
Started
F
Finished in 0.007338 seconds.

  1) Failure:
test_test(MyTest) [test_unit.rb:4]:
<"this"> expected but was
<"that">.

1 tests, 1 assertions, 1 failures, 0 errors

real    0m0.041s
user    0m0.027s
sys     0m0.012s

这可能是您在测试中正在做的事情。 你在做一些复杂的事情吗? 设置数据库? 从互联网上检索一些东西?

Test unit startup isn't particularly slow, and nowhere near 20 seconds.

(11:39) ~/tmp $ cat test_unit.rb 
require 'test/unit'
class MyTest < Test::Unit::TestCase
  def test_test
    assert_equal("this", "that")
  end
end

(11:39) ~/tmp $ time ruby test_unit.rb 
Loaded suite test_unit
Started
F
Finished in 0.007338 seconds.

  1) Failure:
test_test(MyTest) [test_unit.rb:4]:
<"this"> expected but was
<"that">.

1 tests, 1 assertions, 1 failures, 0 errors

real    0m0.041s
user    0m0.027s
sys     0m0.012s

It's probably something you're doing in your tests. Are you doing anything complicated? Setting up a database? Retrieving something from the internet?

笑梦风尘 2024-07-16 08:28:38

完全是在黑暗中拍摄的,但大多数时候我看到启动时间很长,这通常是由于沿途某个 TCP 套接字通信发生了某种反向 DNS 查找。

添加:。

require 'socket'
Socket.do_not_reverse_lookup = true

尝试在测试文件顶部的其他 require 行之后

Complete shot in the dark, but the majority of the time I see long startup times on things, it is usually due to some sort of reverse DNS lookup happening with some TCP socket communication somewhere along the way.

Try adding:

require 'socket'
Socket.do_not_reverse_lookup = true

at the top of your test file after your other require line.

路弥 2024-07-16 08:28:38

你的 test_helper.rb 是什么样的? 您正在使用实例化的装置吗?

self.use_instantiated_fixtures  = true

[编辑]

如果将此设置为 true,请尝试将其设置为 false。

What does your test_helper.rb look like? Are you using instantiated fixtures?

self.use_instantiated_fixtures  = true

[edit]

If this is set to true try setting it to false.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文