我正在使用Ruby on Rails 3并编写测试,但速度太慢了。 是否有一些好的配置或工具可以加快速度?
答案 0 :(得分:4)
除非您需要,否则最大的速度增益可能来自于小心不要打到数据库。模拟对象而不是从数据库中获取它们和/或(例如,如果您使用的是工厂女孩)尽可能使用Factory.build(:stuff)而不是Factory(:stuff)。只有当你这样做时,才应该开始尝试使用spork进一步优化
更新: 就我个人而言,我也开始认为你不应该对你的测试速度感到不知所措。更快更好,但随着应用程序的增长,测试套件将会增长,无论你多么小心,它最终会变得比你想要的慢。我将越来越多地依赖于测试更改代码并在后台工作的autotest gem(guard-rspec做了类似的工作)。当您的应用程序达到1000次测试时,您不希望每次进行更改时都等待整个套件完成,无论测试运行得多么快。
答案 1 :(得分:2)
正如@eml所说,如果你正在使用RSpec,你可以使用Spork。这基本上会激发环境(这是缓慢的部分)然后保持它,每次运行你的规格时都会分叉。
对于“环境始终加载”问题的更一般的解决方案,可以安装rails-sh并在shell中运行测试。
旁注:随着需求时间的优化,Ruby 1.9.3应该稍微缓解这个问题。
答案 2 :(得分:2)
恕我直言,测试的主要减缓部分是灯具的默认配置。如果您的配置是(test/test_helper.rb
):
class ActiveSupport::TestCase
self.use_transactional_fixtures = false
self.pre_loaded_fixtures = false
self.use_instantiated_fixtures = true
然后在每个测试方法之前,从旧数据中清除测试数据库,填充所有表,将所有记录读入内存。
如果您将设置更改为相反的设置:
class ActiveSupport::TestCase
self.use_transactional_fixtures = true
self.pre_loaded_fixtures = true
self.use_instantiated_fixtures = false
然后只为每个测试文件重新创建一次数据库,并且只加载每个测试方法中真正需要的记录。
取决于测试数据集的大小,您是否发现测试数据库创建的时间可以接受。当我有一些非常大的测试数据集时,我在整个测试套件之前只加载了一次灯具,但是那个项目在Rails 1中已经很好了,我已经对其进行了大量修改,所以我不知道怎么做在Rails 3中(至少直到问题在一些新项目中开始变得痛苦;)。
关于测试是否应该访问数据库存在无休止的讨论。如果您认为他们应该(因为数据库合作也应该进行测试),那么您可以检查设置这些参数是否有助于您(或任何人阅读这些答案)。
答案 3 :(得分:0)
我建议使用Spork
和Guard
,这两者都可以与RSpec
完美配合。
Spork
可以帮助您更快地运行测试,
http://railscasts.com/episodes/285-spork
Guard
可以帮助您自动运行测试。
http://railscasts.com/episodes/264-guard
答案 4 :(得分:0)
尝试开发,以便无需加载整个Rails应用程序框架即可执行大多数测试。在你的规范助手中,如果只执行快速测试,请跳过加载环境或rpec / rails,如......
# /spec/spec_helper.rb
if RSpec.configuration.inclusion_filter[:fast]
# Setup required for fast tests in particular (if any)
# ...
else
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
end
RSpec.configure do |config|
# ...
unless RSpec.configuration.inclusion_filter[:fast]
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
end
end
要将测试标记为“快速”,请将, :fast => true
选项添加到其it
来电或周围describe
来电。
要仅运行快速测试,请从命令shell执行rspec --tag fast
。
很难弄清楚如何构建代码,以便测试可以与Rails分开运行(当然,您仍然希望进行不单独运行的功能和集成测试)。
我的库中的一个技巧是避免直接在ActiveRecord模型或其他类似的代码上编写代码,而更喜欢在mixin模块上编写代码。您可以通过将Subject定义为由该模块扩展的对象来测试mixin模块...
describe 'MyModule', :fast => true
subject{ Object.new.tap{|o| o.extend MyModule} }
it 'does something' do
# ...
end
end