9.pytest第三方插件
本文只介绍pytest-ordering
、pytest-rerunfailures
、pytest-xdist
三种插件,报告方面的插件会另起篇幅进行介绍。
顺序执行:pytest-ordering
-
安装:
pip install pytest-ordering
-
使用方式:在方法上加入下面装饰器
-
标记于被测试函数,@pytest.mark.run(order=x)
-
根据order传入的参数来解决运行顺序
-
order值全为正数或全为负数时,运行顺序:值越小,优先级越高
-
正数和负数同时存在:正数优先级高
-
默认情况下,pytest是根据测试方法名由小到大执行的,可以通过第三方插件包改变其运行顺序。
1 # test_abc.py 2 #默认执行方式 3 #示例: 4 import pytest 5 class Test: 6 def test_a(self): 7 print("------->test_a") 8 assert 1 9 def test_b(self): 10 print("------->test_b") 11 assert 0 12 if __name__ == '__main__': 13 pytest.main(["-s","test_abc.py"]) 14 #执行结果: 15 test_abc.py 16 ------->test_a # 默认第一个运行 17 . 18 ------->test_b # 默认第二个运行 19 F
改变顺序后
1 #示例: 2 import pytest 3 class Test: 4 @pytest.mark.run(order=2) 5 def test_a(self): 6 print("------->test_a") 7 assert 1 8 9 @pytest.mark.run(order=1) 10 def test_b(self): 11 print("------->test_b") 12 assert 0 13 if __name__ == '__main__': 14 pytest.main(["-s","test_abc.py"]) 15 #执行结果: 16 test_abc.py 17 ------->test_b # order=1 优先运行 18 F 19 ------->test_a # order=2 晚于 order=1 运行
失败重试:pytest-rerunfailures
-
安装:
pip install pytest-rerunfailures
-
使用方式:pytest --reruns 重试次数 --reruns-delay 次数之间的延时设置(单位:秒)
比如:pytest --reruns 2 --reruns-delay 5 表示:运行失败的用例可以重新运行2次,第一次和第二次的间隔时间为5秒钟
1 import pytest 2 3 4 def test_demo_01(): 5 b = 1 + 2 6 assert 3 == b 7 8 9 def test_demo_02(): 10 b = 1 + 2 11 assert 2 == b 12 13 14 if __name__ == '__main__': 15 pytest.main(['--reruns', '3', '--reruns-delay', '5'])
结果:
D:\Envs\pytest\Scripts\python.exe D:/study/auto-pytest/test_rerun.py ============================= test session starts ============================= platform win32 -- Python 3.7.1, pytest-6.0.2, py-1.9.0, pluggy-0.13.1 rootdir: D:\study\auto-pytest plugins: rerunfailures-9.1.1 collected 2 items test_rerun.py .R [100%]R [100%]R [100%]F [100%] ================================== FAILURES =================================== ________________________________ test_demo_02 _________________________________ def test_demo_02(): b = 1 + 2 > assert 2 == b E assert 2 == 3 test_rerun.py:11: AssertionError =========================== short test summary info =========================== FAILED test_rerun.py::test_demo_02 - assert 2 == 3 ==================== 1 failed, 1 passed, 3 rerun in 15.13s ====================
从结果看,test_rerun.py重试了三次。
并行执行:pytest-xdist
-
前言
有1000条用例,假设每个用例执行需要1分钟。如果一个测试人员执行需要1000分钟才能执行完,当项目非常紧急的时候,我们会用测试人力成本换取时间成本,这个时候多找个小伙伴把任务分成2部分,于是时间缩减一半。如果是十个人一起执行,1000个用例理论上只需100分钟就能完成,时间缩短到了1/10。这是一种并行测试,分布式场景。
同样道理,当我们测试用例非常多的时候,一条条执行,很显然会比较慢,那么如何让测试用例并行执行呢,这就是我们接下来要讲的pytest分布式执行插件pytest-xdist
-
安装:
pip install pytest-xdist
-
使用方法:
pytest -n 3
代表三个并行
运行以下代码,项目结构如下
auto_pytest是项目工程名称 │ conftest.py │ __init__.py │ ├─baidu │ │ conftest.py │ │ test_1_baidu.py │ │ test_2.py │ │ __init__.py │ ├─blog │ │ conftest.py │ │ test_2_blog.py │ │ __init__.py
代码如下:
1 # auto_pytest/conftest.py 2 import pytest 3 4 @pytest.fixture(scope="session") 5 def start(): 6 print("\n打开首页") 7 return "yoyo" 8 9 # auto_pytest/baidu/conftest.py 10 import pytest 11 12 @pytest.fixture(scope="session") 13 def open_baidu(): 14 print("打开百度页面_session") 15 16 ######################################################### 17 18 # auto_pytest/baidu/test_1_baidu.py 19 import pytest 20 import time 21 22 def test_01(start, open_baidu): 23 print("测试用例test_01") 24 time.sleep(1) 25 assert start == "yoyo" 26 27 def test_02(start, open_baidu): 28 print("测试用例test_02") 29 time.sleep(1) 30 assert start == "yoyo" 31 32 if __name__ == "__main__": 33 pytest.main(["-s", "test_1_baidu.py"]) 34 35 36 ######################################################### 37 38 # auto_pytest/baidu/test_2.py 39 import pytest 40 import time 41 42 def test_06(start, open_baidu): 43 print("测试用例test_01") 44 time.sleep(1) 45 assert start == "yoyo" 46 def test_07(start, open_baidu): 47 print("测试用例test_02") 48 time.sleep(1) 49 assert start == "yoyo" 50 51 if __name__ == "__main__": 52 pytest.main(["-s", "test_2.py"]) 53 54 ######################################################### 55 56 # auto_pytest/blog/conftest.py 57 import pytest 58 59 @pytest.fixture(scope="function") 60 def open_blog(): 61 print("打开blog页面_function") 62 63 ######################################################### 64 65 # auto_pytest/blog/test_2_blog.py 66 import pytest 67 import time 68 def test_03(start, open_blog): 69 print("测试用例test_03") 70 time.sleep(1) 71 assert start == "yoyo" 72 73 def test_04(start, open_blog): 74 print("测试用例test_04") 75 time.sleep(1) 76 assert start == "yoyo" 77 78 def test_05(start, open_blog): 79 '''跨模块调用baidu模块下的conftest''' 80 print("测试用例test_05,跨模块调用baidu") 81 time.sleep(1) 82 assert start == "yoyo" 83 84 if __name__ == "__main__": 85 pytest.main(["-s", "test_2_blog.py"])
正常运行需要消耗时间:7.09 seconds
(pytest) D:\study\auto-pytest>pytest =================================== test session starts =================================== platform win32 -- Python 3.7.1, pytest-6.0.2, py-1.9.0, pluggy-0.13.1 rootdir: D:\study\auto-pytest plugins: rerunfailures-9.1.1 collected 7 items baidu\test_1_baidu.py .. [ 28%] baidu\test_2.py .. [ 57%] blog\test_2_blog.py ... [100%] =================================== 7 passed in 7.09s ===================================
设置并行运行数量为3,消耗时间:3.78 seconds,大大的缩短了用例时间
(pytest) D:\study\auto-pytest>pytest -n 3 =================================== test session starts =================================== platform win32 -- Python 3.7.1, pytest-6.0.2, py-1.9.0, pluggy-0.13.1 rootdir: D:\study\auto-pytest plugins: forked-1.3.0, rerunfailures-9.1.1, xdist-2.2.0 gw0 [7] / gw1 [7] / gw2 [7] ....... [100%] =================================== 7 passed in 3.78s ===================================