2011-05-10 55 views
13

很多时候人们写测试时,他们会在状态混乱后自行清理。通常这并不重要,因为对于大多数测试来说对象倾向于被拆除和重新创建,但是有一些不幸的情况是对象的全局状态会持续整个测试运行,并且当您运行测试时依赖于并修改那个全球国家,按照一定的顺序,它们失败了。有没有一种很好的方法来调试RSpec(RSpec2)中依赖于顺序的测试失败?

这些测试和可能的实现显然需要修复,但试图找出在相互影响的测试可能不是完整测试套件中唯一的东西时导致失败的原因是一件很痛苦的事情。当最初并不清楚故障是否与订单相关时尤为困难,并且可能间歇性地或在一台机器上而不是在另一台机器上故障。例如:

rspec test1_spec.rb test2_spec.rb # failures in test2 
rspec test2_spec.rb test1_spec.rb # no failures 

在RSpec的1有some options (--reverse, --loadby)订购的测试运行,但那些已经在RSpec 2消失,只是在调试反正这些问题的最低限度的帮助。

我不确定RSpec 1或RSpec 2默认使用的顺序,但是我过去使用的一个自定义设计的测试套件在每次运行时随机地对测试进行排序,以便更快地发现这些故障。在测试输出中,用于确定排序的种子与结果一起打印,因此即使您必须做一些工作来缩小套件中引起它们的各个测试的范围,也很容易重现故障。然后有一些选项允许您在任何给定的测试文件中按顺序启动和停止,这使您可以轻松地进行二分查找以找到问题测试。

我还没有在RSpec中找到任何这样的实用程序,所以我在这里问:人们发现调试这些类型的顺序依赖测试失败有什么好方法?

+0

这是非常修辞。你能尝试简化这个问题吗? – 2011-05-10 06:32:38

+1

这就是标题/标题的用途。最后一句话。其余的是澄清我的意思是“顺序依赖测试失败”,因为我没有找到其他问题处理,然后试图描述我在寻找什么样的解决方案。如果这两者对于阅读这个问题的其他人都是显而易见的,那么我同意其他的verbage过于夸张,但我不确定这是否明显。 – mmrobins 2011-05-10 06:44:25

回答

4

我不会说我有一个很好的答案,我很想在这里比我的一些更好的解决方案。这说...

我唯一真正的技术,我调试这些问题是添加一个全球性(通过spec_helper)钩打印某些方面的数据库状态(我通常的罪魁祸首)之前和之后每个测试(条件检查是否我关心与否)。最近的一个例子是在我的spec_helper.rb中添加了这样的内容。

Spec::Runner.configure do |config| 
    config.before(:each) do 
    $label_count = Label.count 
    end 

    config.after(:each) do 
    label_diff = Label.count - $label_count 
    $label_count = Label.count 
    puts "#{self.class.description} #{description} altered label count by #{label_diff}" if label_diff != 0 
    end 
end 
+0

感谢您的回答,但它并不能帮助我,因为软件我测试不会有一个数据库,以及订单相关的故障是没有这么预见,一个print语句这一般会帮我:-( – mmrobins 2011-05-20 04:05:50

1

我们对自己的持续集成的设置是水珠一个Rails应用程序的规范/目录并运行它们不受对方一个测试。

需要很多时间,但我们发现5或6个依赖关系。

+4

你有代码为方便?这听起来相当有用。 – 2012-04-23 00:27:28

+5

[古人的智慧...](https://xkcd.com/979/) – Brian 2014-04-15 12:18:55

0

它最有可能的一些状态持续在测试之间,所以确保您的数据库和任何其他数据存储(包括类var和全局变量)在每次测试后重置。 database_cleaner宝石可能会有所帮助。

1

下面是一些快速脏的剧本我写的调试命令相关的故障 - https://gist.github.com/biomancer/ddf59bd841dbf0c448f7

它由两个部分组成。

第一个旨在多次使用不同的种子和转储结果运行rspec诉讼到当前目录中的rspec_[ok|fail]_[seed].txt文件以收集统计信息。

第二部分遍历所有这些文件,提取测试组名称并分析它们对受影响测试的位置,以便对依赖关系进行假设并形成一些“风险”组 - 安全,不安全等。脚本输出解释其他细节和组意义。

该脚本将正常工作只为简单的依赖关系,并只有在受影响的试验失败了一些种子,并通过另一个的,但我认为它仍然是聊胜于无。 在我的情况是复杂的依赖关系时的效果,可以通过另一个测试取消,但这个剧本让我来运行其分析在不同的组转储的一部分多次后得到的方向,特别是只对那些失败(我刚搬到“OK”转出当前目录)。

8

现在有一个--bisect标志,会发现最小的一组测试运行重现故障。请尝试:

$ rspec --bisect=verbose 

使用--fail-fast标志也可能有用。

+0

这项工作是一个了不起的功能。完美地解决了我的问题。谢谢!应该是最好的答案。 – 2016-08-23 12:22:47

相关问题