用例执行一次失败后,可能是由于网络、设备、等等其他因素造成,并不一定就是程序的bug。因此我们需要多执行几次,再好定性它为bug。第三方插件,pytest-rerunfailures
就提供了失败重跑的能力
安装
pip install pytest-rerunfailures
使用
- 命令行参数:
--reruns n
(重新运行次数),--reruns-delay m
(等待运行秒数)
例如:
pytest pytest-demo.py --reruns 2 --reruns-delay 3
pytest-demo.py
测试文件中的用例,如果执行失败,则会在3秒后再运行。最多再运行2次、
- 装饰器使用:
@pytest.mark.flaky(reruns=n , reruns_delay=m)
效果同上
使用案例
判断随机生成的数字恰好是6:
import pytest
from random import randint
def test01():
assert randint(1, 10) == 6
if __name__ == '__main__':
pytest.main(['reRun.py', '-v','--reruns=3'])
执行结果:
collecting ... collected 1 item
reRun.py::test01 RERUN [100%]
reRun.py::test01 RERUN [100%]
reRun.py::test01 RERUN [100%]
reRun.py::test01 FAILED [100%]
================================== FAILURES ===================================
___________________________________ test01 ____________________________________
def test01():
> assert randint(1, 10) == 6
E assert 8 == 6
E +8
E -6
reRun.py:6: AssertionError
=========================== short test summary info ===========================
FAILED reRun.py::test01 - assert 8 == 6
========================= 1 failed, 3 rerun in 0.31s ==========================
***Repl Closed***
第一次执行后,执行失败,又重试了3次。实际总共执行了4次。 上述效果等同于:
import pytest
from random import randint
@pytest.mark.flaky(reruns=3)
def test01():
assert randint(1, 10) == 6
if __name__ == '__main__':
pytest.main(['reRun.py', '-v'])
用例执行的时候,对应的setup和fixture都会被执行:
import pytest
from random import randint
@pytest.fixture
def step1():
print("【+】fixture function")
@pytest.mark.flaky(reruns=3)
@pytest.mark.usefixtures("step1")
def test01():
assert randint(1, 10) == 6
if __name__ == '__main__':
pytest.main(['reRun.py', '-s'])
执行结果
collected 1 item
reRun.py 【+】fixture function
R【+】fixture function
R【+】fixture function
R【+】fixture function
.
========================= 1 passed, 3 rerun in 0.31s ==========================
***Repl Closed***
注意
- 装饰器的优先级大于命令行参数,如果同时设置了rerun,则优先使用装饰器的