我开始尝试加快测试速度,主要是遵循这个 railscast的建议。所以你不必看它,那些是:
- 将“bundle exec 规范”替换为“bin/rspec 规范”
- 在过滤器之前摆脱多余的
- 标记为单独运行的慢速测试
- 用构建替换了不必要的工厂创建
- 使用 Zeus 加快启动时间
- 将 VCR 应用于涉及外部 API 的示例
- 延迟垃圾回收
- (我暂时跳过了并行测试,因为我想深入了解这个问题,而并行测试似乎只会最小化/屏蔽它)
无论如何,我无法弄清楚这些更改是否取得了很大的成就,因为我的测试的运行时间是高度可变的。(即使当我走出我一直在为这些测试工作的分支时,它们也是可变的——似乎是预先存在的东西导致了问题)。我现在已经运行了完全相同的测试套件,并获得了广泛的运行时间,从 52 秒到近 1 分 45 秒!再次,完全相同的测试。
此外,总体趋势似乎是,如果我连续运行几次测试,每次运行时间都会增加约 20 秒的间隔。然后,如果我在 spec_helper 中更改一些小的内容或等待一段时间(我认为是后者——我知道这发生在我对垃圾收集进行小的更改时),时间会倒退。
我的猜测是这个问题与垃圾收集有关——但理想情况下,我现在这样做更有效率。我让它每 15 秒收集一次垃圾,
spec_helper.rb
config.before(:all) { DeferredGarbageCollection.start }
config.after(:all) { DeferredGarbageCollection.reconsider }
支持/deferred_garbage_collection.rb
class DeferredGarbageCollection
DEFERRED_GC_THRESHOLD = (ENV['DEFER_GC'] || 15.0).to_f
@@last_gc_run = Time.now
def self.start
GC.disable if DEFERRED_GC_THRESHOLD > 0
end
def self.reconsider
if DEFERRED_GC_THRESHOLD > 0 && Time.now - @@last_gc_run >= DEFERRED_GC_THRESHOLD
GC.enable
GC.start
GC.disable
@@last_gc_run = Time.now
end
end
end
然后,当这导致上述问题时,我切换到更简单的每十次测试收集系统:
spec_helper.rb
config.after(:each) do
counter += 1
if counter > 9
GC.enable
GC.start
GC.disable
counter = 0
end
end
config.after(:suite) do
counter = 0
end
我试图将其隔离为一组测试(模型/请求/控制器),但它们似乎都显示出与它们消耗的大致时间有关的一些可变性。
任何想法这里出了什么问题?
编辑——这里发生的事情的证明/例子:
Finished in 22.88 seconds
48 examples, 0 failures
➜ my_app git:(faster-tests) ✗>zeus test spec/models
................................................
Finished in 34.89 seconds
48 examples, 0 failures
➜ my_app git:(faster-tests) ✗>zeus test spec/models
................................................
Finished in 44.68 seconds
48 examples, 0 failures
➜ my_app git:(faster-tests) ✗>zeus test spec/models
................................................
Finished in 14.36 seconds
48 examples, 0 failures
➜ my_app git:(faster-tests) ✗>zeus test spec/models
................................................
Finished in 18.74 seconds
48 examples, 0 failures
➜ my_app git:(faster-tests) ✗>
请注意,它最终似乎会重置。