为什么Test :: Unit测试版启动速度如此之慢?

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

当我运行这样的测试夹具(测试轨道模型类)时,开始执行这些测试需要20-30秒(显示“已加载的套件……”)。 是什么赋予了?

 >ruby test\unit\category_test.rb require File.dirname(__FILE__) + '/../test_helper' class CategoryTest '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测试服务器 。

作者的一句话:

“每次在Rails应用程序中运行测试时,都会加载整个环境,包括在两次连续运行之间不会更改的库。这可能需要相当长的时间。如果我们可以加载一次环境怎么办?在每次运行之前重新加载更改的部分?引入RailsTestServing。

使用RailsTestServing,单个测试文件的运行时间从我的计算机上的8秒下降到0.2秒。 这是x40的速度提升。 现在,在TextMate中点击⌘R之前我没有三思而后行。 感觉很自由!“

(这是过去一周在Rails Envy播客中的特色,我发现了这一点。)

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

20-30秒听起来慢。 在测试运行之前是否需要加载很多灯具,或者数据库运行缓慢?

Ruby的gem工具遵循路径发现算法,显然,不是Windows(我从你的ruby -v看到)友好。

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

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

看起来Test :: Unit是最简单的,但也是使用Ruby进行unit testing的最慢方法之一。 其中一个选择是ZenTest 。

测试单元启动不是特别慢,并且不到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 

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

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

尝试添加:

 require 'socket' Socket.do_not_reverse_lookup = true 

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

你的test_helper.rb是什么样的? 你在使用实例化的灯具吗?

 self.use_instantiated_fixtures = true 

[编辑]

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