Dmy*_*iak 6 ruby rspec ruby-on-rails rspec2 rspec3
我有一些较慢的规格,我想优化.这种规范的例子如下:
require 'rspec'
class HeavyComputation
def compute_result
sleep 1 # something compute heavy here
"very big string"
end
end
describe HeavyComputation, 'preferred style, but slow' do
subject { described_class.new.compute_result }
it { should include 'big' }
it { should match 'string' }
it { should match /very/ }
# +50 others
end
Run Code Online (Sandbox Code Playgroud)
这是非常易读的,我对它很满意,除了每个额外的规范都会在总运行时间内增加至少1秒.这是不可接受的.
(请不要讨论HeavyComputation课程的优化,因为它超出了本问题的范围).
所以我要求的是这样的规格:
describe HeavyComputation, 'faster, but ugly' do
subject { described_class.new.compute_result }
it 'should have expected result overall' do
should include 'big'
should match 'string'
should match /very/
# +50 others
end
end
Run Code Online (Sandbox Code Playgroud)
这显然是更好的性能,因为运行它的时间总是几乎不变.问题是失败很难追查,阅读起来不是很直观.
理想情况下,我希望两者兼而有之.这些方面的东西:
describe HeavyComputation, 'what I want ideally' do
with_shared_setup_or_subject_or_something_similar_with do
shared(:result) { described_class.new.compute_result }
subject { result }
it { should include 'big' }
it { should match 'string' }
it { should match /very/ }
# +50 others
end
end
Run Code Online (Sandbox Code Playgroud)
但不幸的是,我无法看到哪里开始实施它.它有许多潜在的问题(如果在共享结果上调用钩子的话).
如果现有解决方案存在问题我想知道什么.如果不是,那么解决它的最佳方法是什么?
@Myron Marston 提供了一些灵感,所以我第一次尝试以或多或少可重用的方式实现它,最终得到了以下用法(请注意shared_subject):
describe HeavyComputation do
shared_subject { described_class.new.compute_result }
it { should include 'big' }
it { should match 'string' }
it { should match /very/ }
# +50 others
end
Run Code Online (Sandbox Code Playgroud)
这个想法是只在第一个规范上渲染主题一次,而不是在共享块中。这使得几乎没有必要改变任何东西(因为所有的钩子都会被执行)。
当然,shared_subject假设共享状态及其所有怪癖。
但每个新的嵌套context都会创建一个新的共享主题,并在某种程度上消除状态泄漏的可能性。
更重要的是,为了处理状态泄漏(如果这些泄漏),我们需要做的就是替换shared_subject回subject. 然后您将运行正常的 RSpec 示例。
我确信该实现有一些怪癖,但应该是一个很好的开始。
| 归档时间: |
|
| 查看次数: |
775 次 |
| 最近记录: |