【注意】flaky和pytest-rerunfailures好像不能同时安装。否则flaky不好使。
测试过程中,你是否遇到过这样的情况:
1、大部分时间里测试都是通过的,只是偶尔会失败
2、测试偶尔失败的原因是,你的测试中使用了不是很稳定的第三方模块,你没有办法去提高第三方模块的稳定性
3、测试失败之后,往往重新执行测试,测试就能通过。
如果你使用的是nose或者py.test编写和执行测试,对于上面的情况,你可以删除最不稳定的case,或者使用@skip装饰器跳过经常测试失败的case。但是这并不是一个很好的方法。因为大量的case中,你没办法判断哪些case最容易失败。
那么有没有更好的办法,在这些不稳定的case失败之后,能够自动重新运行这些失败的case呢?当然有。那就是Flaky插件。
安装官网的介绍,Flaky is a plugin for nose or py.test that automatically reruns flaky tests。他是一个nose和py.test的插件,能够在那些不稳定的case失败之后,重复执行这些case。官网:http://opensource.box.com/flaky/
pip install flaky
在你测试过程中激活Flaky功能:
1)对于nose,执行
nosetests --with-flaky
2)对于py.test
py.test会自动激活Flaky不需要你做任何工作。
from flaky import flaky
@flaky
def test_something_that_usually_passes(self):
value_to_double = 21
result = get_result_from_flaky_doubler(value_to_double)
self.assertEqual(result, value_to_double * 2, 'Result doubled incorrectly.')
【解析】
只需在测试case上加上@flaky即可。这样,当这个测试失败的时候,会自动再次执行这测试1次。
flaky接收两个参数:max_runs and min_passes。max_runs表示测试失败之后,会重复执行这个测试的次数。min_passes表示执行max_runs这么多次中,成功的次数超过min_passes的话,则认为这个case就pass了。
我们将上面的脚本改为:
@flaky(max_runs=3, min_passes=2)
def test_something_that_usually_passes(self):
"""This test must pass twice, and it can be run up to three times."""
value_to_double = 21
result = get_result_from_flaky_doubler(value_to_double)
self.assertEqual(result, value_to_double * 2, 'Result doubled incorrectly.')
【解析】
上面的脚本中有:@flaky(max_runs=3, min_passes=2),代表的意思是:如果test_something_that_usually_passes第一次执行失败了,将会再次重复执行它3次,如果这3次中有2次成功了,则认为这个测试通过了。
@flaky
class TestMultipliers(TestCase):
def test_flaky_doubler(self):
value_to_double = 21
result = get_result_from_flaky_doubler(value_to_double)
self.assertEqual(result, value_to_double * 2, 'Result doubled incorrectly.')
@flaky(max_runs=3)
def test_flaky_tripler(self):
value_to_triple = 14
result = get_result_from_flaky_tripler(value_to_triple)
self.assertEqual(result, value_to_triple * 3, 'Result tripled incorrectly.')
【解析】
在测试类上应用flaky,那么该测试类下面的所有测试,都将应用flaky。就拿上面的例子来讲,test_flaky_doubler失败后将重复执行1次,而test_flaky_tripler失败后将重复执行3次。
正常情况下,测试完成后将输出flaky的测试报告,该报告中显示了有哪些测试重复执行了以及重复执行的情况。
如果不想在测试完成后输出flaky报告,可以在执行测试的时候加上--no-flaky-report参数:
py.test --no-flaky-report
py.test --force-flaky
【说明】使用这个方法,就不需要在脚本中为每一个测试样例或者测试类指定@flaky。也不需要导入flaky模块。
py.test --force-flaky --max-runs=3 --min-passes=2
这种情况下,在脚本中的max-runs和min-passes将覆盖命令行上的参数。也就是说最终起作用的参数还是脚本中的参数,如果脚本中没有指定这些参数,那么命令行上的参数才起作用。