pytest系列教程——11、用例重复执行、顺序执行、分布式执行
重复执行
当我们想要复现某个偶现的问题时候,重复执行测试脚本当然是最好的选择。不用写个循环去执行,pytest提供了pytest-repeat
插件去做这件事。
安装
pip install pytest-repeat
使用
- 直接在运行脚本本使用
import pytestfrom random import randintdef test01(): assert randint(1,10) % 2 == 0if __name__ == '__main__': pytest.main(['重复执行.py', '-s','--count=5'])
运行结果:
collected 5 items重复执行.py ..F..================================== FAILURES ===================================_________________________________ test01[3-5] _________________________________def test01():>assert randint(1,10) % 2 == 0Eassert (7 % 2) == 0E + where 7 = randint(1, 10)重复执行.py:6: AssertionError=========================== short test summary info ===========================FAILED 重复执行.py::test01[3-5] - assert (7 % 2) == 0========================= 1 failed, 4 passed in 0.19s =========================***Repl Closed***
- 在命令行中使用,效果一样:
pytest 重 复执行.py -s --count 5
- 使用装饰器执行:
import pytestfrom random import randint@pytest.mark.repeat(5)def test01(): assert randint(1,10) % 2 == 0if __name__ == '__main__': pytest.main(['重复执行.py', '-s'])
效果同上:
重复执行.py FF...================================== FAILURES ===================================_________________________________ test01[1-5] _________________________________ @pytest.mark.repeat(5) def test01():>assert randint(1,10) % 2 == 0Eassert (5 % 2) == 0E + where 5 = randint(1, 10)重复执行.py:7: AssertionError_________________________________ test01[2-5] _________________________________ @pytest.mark.repeat(5) def test01():>assert randint(1,10) % 2 == 0Eassert (9 % 2) == 0E + where 9 = randint(1, 10)重复执行.py:7: AssertionError=========================== short test summary info ===========================FAILED 重复执行.py::test01[1-5] - assert (5 % 2) == 0FAILED 重复执行.py::test01[2-5] - assert (9 % 2) == 0========================= 2 failed, 3 passed in 0.19s =========================***Repl Closed***
顺序执行
有如下代码,希望它的执行顺序是按照我所设定的场景执行登录
->增加用户
->退出
,但是实际运行结果是按照代码顺序进行的,例如:
import pytestfrom time import sleepdef testLogin(): print("登录")def testLogout(): print("退出")def testAddUser(): print("增加用户")if __name__ == '__main__': pytest.main(['非顺序执行.py', '-s'])
结果:
collected 3 items非顺序执行.py 登录.退出.增加用户.============================== 3 passed in 3.12s ==============================***Repl Closed***
这个时候我们就可以使用pytest-ordering
插件实现指定顺序运行。
安装
pip install pytest-ordering
使用
import pytestfrom time import sleep@pytest.mark.run(order=1)def testLogin(): sleep(1) print("登录")@pytest.mark.run(order=3)def testLogout(): sleep(1) print("退出")@pytest.mark.run(order=2)def testAddUser(): sleep(1) print("增加用户")if __name__ == '__main__': pytest.main(['顺序执行.py', '-s'])
运行结果:
collected 3 items顺序执行.py 登录.增加用户.退出.============================== 3 passed in 3.12s ==============================***Repl Closed***
分布式运行
当我有100条脚本的时候,每条执行大概1秒,如果顺序执行完的话,至少100秒。为了缩短测试时间,我们引入了并发执行的插件pytest-xdist
。
安装
pip install pytest-xdist
使用
先对比下我们最开始的例子,我这里写6条case,每条执行一秒。总共耗时可以看下:
import pytestfrom time import sleepdef test01(): sleep(1) print("test01")def test02(): sleep(1) print("test02")def test03(): sleep(1) print("test03")def test04(): sleep(1) print("test04")def test05(): sleep(1) print("test05")def test06(): sleep(1) print("test06")if __name__ == '__main__': pytest.main(['非分布式执行.py', '-s'])
运行结果:
collected 6 items非分布式执行.py test01.test02.test03.test04.test05.test06.============================== 6 passed in 6.10s ==============================***Repl Closed***
可见,运行时间6.10s
当我们引入分布式的执行参数,运行参数增加 -n number
。number
是几,则就代表几个并行数量
import pytestfrom time import sleepdef test01(): sleep(1) print("test01")def test02(): sleep(1) print("test02")def test03(): sleep(1) print("test03")def test04(): sleep(1) print("test04")def test05(): sleep(1) print("test05")def test06(): sleep(1) print("test06")if __name__ == '__main__': pytest.main(['分布式执行.py', '-s', '-n=3'])
优化后结果,缩减为3.17s:
gw0 I / gw1 I / gw2 Igw0 [6] / gw1 [6] / gw2 [6]......============================== 6 passed in 3.17s ==============================***Repl Closed***
原理
- xdist的分布式类似于一主多从的结构,master机负责下发命令,控制slave机;slave机根据master机的命令执行特定测试任务
- 在xdist中,主是master,从是workers
- xdist会产生一个或多个workers,workers都通过master来控制
- 每个worker负责执行完整的测试用例集,然后按照master的要求运行测试,而master机不执行测试任务