插件在前面介绍的时候已经讲到了一部分,例如 pytest-ordering(用例先后顺序一章) , pytest-assume(夹具一章) 。本章学习学习其他几个插件。
pytest-xdist
多线程运行用例
安装
pip install pytest-xdist
示例
def test01(): print("--01--") def test02(): print("--02--") def test03(): print("--03--") def test04(): print("--04--") def test05(): print("--05--")
正常运行结果
test_a.py::test01 --01-- PASSED test_a.py::test02 --02-- PASSED test_a.py::test03 --03-- PASSED test_a.py::test04 --04-- PASSED test_a.py::test05 --05-- PASSED ========================= 5 passed in 0.03s ========================
多线程运行结果
test_a.py::test03 test_a.py::test01 [gw0] PASSED test_a.py::test01 [gw1] PASSED test_a.py::test03 test_a.py::test02 test_a.py::test04 [gw0] PASSED test_a.py::test02 [gw1] PASSED test_a.py::test04 test_a.py::test05 [gw1] PASSED test_a.py::test05 ========================= 5 passed in 0.97s ==================
你会发现多线程运行时间还慢了一些,这是因为启动多线程需要时间。所以在简单的测试用例上不推荐用多线程,直接正常跑用例即可。
pytest-dependency
用例依赖
下载
pip install pytest-dependency
示例
import pytest @pytest.mark.xfail(reason="deliberate fail") @pytest.mark.dependency() def test01(): # print("--01--") raise Exception('111') @pytest.mark.dependency(depends=['test01']) def test02(): print("--02--") @pytest.mark.dependency() def test03(): print("--03--") @pytest.mark.dependency() def test04(): print("--04--") @pytest.mark.dependency(depends=['test03','test04']) def test05(): print("--05--") """ Case/test_a.py::test01 XFAIL (deliberate fail) Case/test_a.py::test02 SKIPPED (test02 depends on test01) Case/test_a.py::test03 --03-- PASSED Case/test_a.py::test04 --04-- PASSED Case/test_a.py::test05 --05-- PASSED =================== 3 passed, 1 skipped, 1 xfailed in 0.38s =================== """
❝先看test05,次用例依赖于test03以及test04,如果test03或test04失败,则跳过执行,相反,test03以及test04都必须成功才能执行。且必须打上标记位@pytest.mark.dependency(),否则无效。再看test02,因为依赖test01,而test01我们主动异常,并且给上了xfail,预失败标志,所以它本身就是不通过的,所以test02会随之跳过执行。
❞
按名称使用
import pytest @pytest.mark.xfail(reason="deliberate fail") @pytest.mark.dependency(name='01') def test01(): # print("--01--") raise Exception('111') @pytest.mark.dependency(depends=['01']) def test02(): print("--02--") @pytest.mark.dependency(name='03') def test03(): print("--03--") @pytest.mark.dependency(name='04') def test04(): print("--04--") @pytest.mark.dependency(depends=['03','04']) def test05(): print("--05--")
❝使用name来进行取别名,名称必须是唯一的。
❞
使用测试类
import pytest class Test_A: @pytest.mark.xfail(reason="deliberate fail") @pytest.mark.dependency() def test01(self): # print("--01--") raise Exception('111') @pytest.mark.dependency(depends=['Test_A::test01']) def test02(self): print("--02--") @pytest.mark.dependency() def test03(self): print("--03--") @pytest.mark.dependency() def test04(self): print("--04--") @pytest.mark.dependency(depends=['Test_A::test03','Test_A::test04']) def test05(self): print("--05--") """ Case/test_a.py::Test_A::test01 XFAIL (deliberate fail) Case/test_a.py::Test_A::test02 SKIPPED (test02 depends on Test_A::te...) Case/test_a.py::Test_A::test03 --03-- PASSED Case/test_a.py::Test_A::test04 --04-- PASSED Case/test_a.py::Test_A::test05 --05-- PASSED =================== 3 passed, 1 skipped, 1 xfailed in 0.37s =================== """
取别名也可以在类中使用:
import pytest class Test_A: @pytest.mark.xfail(reason="deliberate fail") @pytest.mark.dependency(name='01') def test01(self): # print("--01--") raise Exception('111') @pytest.mark.dependency(depends=['01']) def test02(self): print("--02--") @pytest.mark.dependency(name='03') def test03(self): print("--03--") @pytest.mark.dependency(name='04') def test04(self): print("--04--") @pytest.mark.dependency(depends=['03','04']) def test05(self): print("--05--")
参数化
import pytest @pytest.mark.parametrize("x,y", [ pytest.param(0, 0, marks=pytest.mark.dependency(name="a1")), pytest.param(0, 1, marks=[pytest.mark.dependency(name="a2"), pytest.mark.xfail]), ]) def test_a(x,y): assert y <= x @pytest.mark.parametrize("u,v", [ pytest.param(1, 2, marks=pytest.mark.dependency(name="b1", depends=["a1", "a2"])) ]) def test_b(u,v): pass """ Case/test_a.py::test_a[0-0] PASSED Case/test_a.py::test_a[0-1] XFAIL Case/test_a.py::test_b[1-2] SKIPPED (test_b[1-2] depends on a2) =================== 1 passed, 1 skipped, 1 xfailed in 0.38s =================== """
pytest-rerunfailures
针对不通过的用例运行多次,排除网络等不稳定因素
下载
pip install pytest-rerunfailures
示例
def test01(): assert False def test02(): assert True
运行命令
pytest -vs --reruns=5
❝--reruns=5,5可以修改成任何数字,此处的意思是,失败重复5次。在跑通后就会自动停止,可以试试下面的代码:
❞
import random def test01(): num = random.randint(1,5) assert num == 2
pytest-repeat
❝使用count指定重跑次数:pytest --count=3 路径,不管有没有运行成功或者失败,都会重跑3次.它也可以搭配其他的命令一起使用。
❞
下载
pip install pytest-repeat
示例
import random def test01(): num = random.randint(1,5) assert num == 2
执行命令
pytest -vs --count=3
test_a.py::test01[1-3] PASSED test_a.py::test01[2-3] FAILED test_a.py::test01[3-3] FAILED
可以看到结果,不论是否通过都会执行完三次。也可以跟pytest的内部命令一起使用,例如-x:
pytest -vs --count=3 -x
第一次失败之后停止运行。
FAILED test_a.py::test01[1-3] - assert 4 == 2 !!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!! ======================================= 1 failed in 0.18s ===================
pytest-random-order
让用例随机执行,用来测试用例在无序执行时是否正常 。用的非常的少。
下载
pip install pytest-random-order
示例
def test01(): assert True def test02(): assert True def test03(): assert True def test04(): assert True
执行命令
pytest -vs --random-order
test_a.py::test04 PASSED test_a.py::test02 PASSED test_a.py::test03 PASSED test_a.py::test01 PASSED
可以看到执行顺序是乱的(随机的)。
本章的插件内容在项目中还是很实用的,所以,自己一定要好好揣摩~