let的正常行为本质上是绑定到一个示例块(即它阻塞。)这在大多数情况下都很好,但是如果碰巧在let中使用多个let创建大对象会出现严重问题例子。在这种情况下,实例变量几乎成为测试套件健全性的必要条件。
时间将如此复合:
如果调用的示例数超过3,则此时间很快成为问题。
大多数人会说使用实例变量是异端邪说,但是目前的状态让它看起来像是过度教条式的狂言而没有太多的研究相反。在我阅读的任何支持let的文章中,唯一的论点是对延迟加载和范围问题的一些吸引力,这两个问题在编写良好的测试中都是无关紧要的。
延迟加载在测试中似乎没有意义,因为它只在您不确定是否需要数据时才有用。如果是这种情况,为什么还要为该测试首先构建数据呢?
如果你没有在你的测试中改变你的对象(暗示:你不应该永久存根),那么实例变量可能永远不会成为问题。如果是,耦合不是变量的错误,它就是测试本身。
TL; DR:有一种已知方法将let类型语句绑定到备用块区域吗?理想情况下,我想将它绑定到描述和上下文块以缓解此问题。
示例:
describe 'Person' do
local_bind let(:person) { Person.new(actual_data) }
context 'It has no data' do
local_bind let(:person) { Person.new(blank_data) }
# tests
end
end
local_bind将let绑定到当前块上下文而不是运行它的示例。当然这是推测语法,但在这里给出了一般性的想法。
这将允许我们声明一个对象用于块区域内的所有示例,这将大大减少let示例仅记忆的不良影响。
虽然这些问题不会明显地显示在基本对象上(50个调用* 0.001实例化仍然相当快),但在更昂贵的问题上会变得明显可见(50个调用* 0.1 = 5秒。)
我已经看过很久以前的事情了,当他们以某种方式进入规范助手并在不良的性能抽象中到处使用时,你可以想象一下3,500个测试的测试套件如何能够迅速屈服于它的'膝盖。到目前为止观察到的差异是从JSON问题的8:15到1:57所花费的时间减少了75%,当我这样做时,让我确定我估计下降到20秒以下。努力获得证据。
答案 0 :(得分:-1)
https://github.com/rspec/rspec-core/issues/1246
我已经与RSPEC核心团队讨论过这个问题,他们并不打算清除这个不幸的命名约定。相反,他们似乎坚持认为程序员不会更好地知道,必须抓住他们的手,然后再接受。一件工作,很多...