ruby – RSPEC让vs实例创建昂贵的对象
在RSPEC中,Let的行为是通过单个示例(它阻止)进行记忆,但在某些情况下,这可能会导致一些潜在的令人讨厌的副作用.
我注意到如果你设法尝试创建任何被认为是昂贵的东西,比如一个大型的模拟器,整个对象的创建将重复它所调用的每一个例子. 对此进行故障排除的第一步是将模拟数据下载到大小,这将大部分运行时间从约30秒减少到~0.08秒.通过将一个没有任何形式的突变被调用3次的let变量传递给实例,速度可以进一步提高(在这种情况下为-0.02到-0.04). 通常情况下,可以推测懒惰的评估是可取的,并且在某些情况下这样的事情是安全的代价.在大型测试套件(3000次测试)的背景下,甚至0.01-0.02秒的差异通常足以导致20-30秒的膨胀.当然,在某些情况下,这是任意编号,但您可以看到为什么这是不合需要的并且会产生复合问题. 我的问题是: >在什么情况下不再是一个可行的选择? 感谢您的时间! 解决方法
正如您似乎意识到的那样,除了您使用它的示例之外,基本上只是让您不要评估变量.如果你在十个例子中使用它,那么你确实会在昂贵的操作中获得十次点击.
所以对于你的第一个问题,我不知道我能提供一个有用的答案.这是非常情境化的,但是如果你经常使用变量并且这是一个昂贵的操作,我会说让它不可行.但根据您的需求,它可能仍然是最佳选择 – 也许您必须在大多数示例中重置状态,但不是全部.在这种情况下,操作的费用可能不值得尝试在少数情况下分享它的痛苦. 对于你的第二个问题,我想说尝试让我们在一个街区内工作可能不是一个好主意.这是一个before(:all)块和一个实例变量的情况. 你的第三个问题是我认为真正的肉在哪里,所以请耐心等待. FactoryGirl真的不会改变你的问题.它将构建并可选地保存对象,但您仍需要决定在何处以及如何使用它.如果你开始将它弹出到之前(:每个)块,或者在大多数示例中调用构建器,你仍然会有性能命中. 根据您的需要,您可以在before(:all)块甚至before(:suite)块中执行昂贵的操作(例如,在spec_helper.rb中配置).这样做的好处是可以减少对昂贵操作的点击次数,但缺点是如果您正在修改数据,则会对所有其他测试进行修改.这显然会导致许多难以调试的问题.如果您的数据需要通过多个示例进行更改,然后重置为原始状态,那么您将遇到某种性能损失或自己设计的自定义逻辑. 如果您的数据主要位于ActiveRecord对象中,并且您并不热衷于存根/模拟以防止访问数据库,那么您可能会遇到缓慢的测试问题. Fixtures可以与事务一起使用,并且可以比工厂更快,但根据您的数据库架构,关系等可能很难维护.我相信您可以在before(:suite)块中使用工厂,然后交易仍然有效,但这并不一定比固定装置更容易维护. 如果您的数据只是CPU数据库而不是数据库记录,则可以设置一组对象并通过Marshal模块对其进行序列化.然后你可以在一个let块中预加载它们,只需一个磁盘命中(或者内存,如果你将Marshalled字符串存储在内存中): # In irb or pry or even spec_helper.rb object = SomeComplexThing.new object.prepare_it_with_expensive_method_call_fun Marshal.dump(object) # Store the output of this somewhere # In some_spec.rb let(:thing) { Marshal.load(IO.read("serialized_thing")) } 这样做的好处是可以完全序列化对象的状态,并在不重新计算昂贵数据的情况下完全恢复它.对于像ActiveRecord模型这样的非常复杂的对象,这可能不会有效,但它对于您自己设计的更简单的数据结构非常方便.您甚至可以通过实现marshal_dump和marshal_load方法来实现自己的转储/加载逻辑(请参阅上面链接的Marshal文档),这可以在测试之外使用. 如果您的数据足够简单,您甚至可以使用以下设置: # In spec_helper.rb RSpec.configure do |config| config.before(:suite) do @object = SomeComplexThing.new @object.prepare_it_with_expensive_method_call_fun end end # In a test let(:thing) { @object.dup } 这并不一定适用于所有情况,因为dup是一个浅层副本(有关详细信息,请参阅the Ruby docs),但是您可以理解 – 您正在构建副本而不是重新计算任何昂贵的东西会伤害您. 我希望这些信息有所帮助,因为我不确定我完全理解你需要什么. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |