pytest测试框架系列 - pytest-xdist 分布式、多进程并发执行用例你会吗?

2021/7/12 7:08:04

本文主要是介绍pytest测试框架系列 - pytest-xdist 分布式、多进程并发执行用例你会吗?,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

## 前言 场景:随着项目越来越大、复杂,用例越来越多,串行的执行就需要太多的时间,就像测试部门一样,项目太多,项目完成的时间就越来越久,这就需要我们招聘更多的人,同时来测试项目,这样就提高了测试效率,但是需要尽量减少项目测试之间的关联性、耦合性。 Pytest 框架提供了一个`pytest-xdist` 插件帮我们做了这件事情,我们只需要简单的使用即可。 ## **用例需要并发执行注意点** - 每条用例是独立的,没有依赖关系,完全解耦,用例可以完全独立运行 - 用例执行没有顺序,随机顺序都能正常执行 - 每个用例都能重复运行,运行结果不会影响其他用例 ## pytest-xdist 详解 (建议掌握程度:☆☆☆☆☆) ### 安装 - 在命令行窗口输入: `pip install pytest-xdist` - 查看安装版本:`pip show pytest-xdist` ![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=20210710133836425.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA0NTQxMTc=,size_16,color_FFFFFF,t_70) ### 使用 使用方法 : - pytest -n num (代表使用num个CPU) - pytest -n auto - n auto:可以自动检测到系统的CPU核数;从测试结果来看,检测到的是逻辑处理器的数量 - 使用auto等于利用了所有CPU来跑用例,此时CPU占用率会特别高 说明:建议最多使用1/2的CPU个数来进行执行,消耗资源太多,导致电脑太卡 **先看下不使用分布式执行** ```python # !/usr/bin/python3 # _*_coding:utf-8 _*_ """" # @Time  :2021/7/10 13:31 # @Author  : king # @File   :test_xdist.py # @Software :PyCharm # @blog :https://blog.csdn.net/u010454117 # @WeChat Official Account: 【测试之路笔记】 """ import pytest import time def test_01(): time.sleep(1) print("我是 test_01 用例") assert True def test_02(): time.sleep(1) print("我是 test_02 用例") assert True def test_03(): time.sleep(1) print("我是 test_03 用例") assert True def test_04(): time.sleep(1) print("我是 test_04 用例") assert True def test_05(): time.sleep(1) print("我是 test_05 用例") assert True def test_06(): time.sleep(1) print("我是 test_06 用例") assert True def test_07(): time.sleep(1) print("我是 test_07 用例") assert True def test_08(): time.sleep(1) print("我是 test_08 用例") assert True def test_09(): time.sleep(1) print("我是 test_09 用例") assert True def test_10(): time.sleep(1) print("我是 test_10 用例") assert True def test_11(): time.sleep(1) print("我是 test_11 用例") assert True def test_12(): time.sleep(1) print("我是 test_12 用例") assert True if __name__ == '__main__': pytest.main(["-s", "-v"]) ``` 执行结果:代码每个用例sleep了1秒,可以看出来串行需要12秒,如果是成千上万的用例,需要的时间就特别长了 ![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=20210710143752943.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA0NTQxMTc=,size_16,color_FFFFFF,t_70) **使用 pytest -n num** 示例还是上面示例,直接看执行结果:命令输入`pytest -n 3 test_xdist.py`, 看执行时间是不是从12.20秒到4.75秒,是不是减少了2倍 ![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=20210710144520237.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA0NTQxMTc=,size_16,color_FFFFFF,t_70) **使用 pytest -n auto** 示例还是上面示例,直接看执行结果:命令输入`pytest -n auto test_xdist.py`,启动了8个进程,代表执行电脑总共8个虚拟CPU,因为用例不多,加上启动进程需要时间,所以跟3个进行消耗时间差不多,如果用例越多效果越明显,建议使用1/2的电脑CPU运行即可 ![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=20210710145041204.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA0NTQxMTc=,size_16,color_FFFFFF,t_70) ### 看看多个文件时执行情况 - `test_xdist.py` 和 `test_xdist_02.py` 和 `test_xdist_03.py` 里面代码 都是一样 - 使用`pytest -v -n 3 test_xdist.py test_xdist_02.py test_xdist_03.py` 执行 执行结果:看结果是,先收集了所有用例,创建了3个执行器,分别执行对应的用例,3个执行器都是从第一个文件往后依次执行 ![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=20210710150312832.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA0NTQxMTc=,size_16,color_FFFFFF,t_70) ## **问题:如果按照作用域分配给worker用例分别执行该怎么做** 如果我们想要按照用例的作用域进行执行,该怎么处理呢?3个执行器只能分别执行一个模块(一个py文件)或者同一个文件里面同一个类只给一个执行器执行。 通过`pytest-xdist`的源码发现有这一段参数配置说明: ```python group.addoption( "--dist", metavar="distmode", action="store", choices=["each", "load", "loadscope", "loadfile", "no"], dest="dist", default="no", help=( "set mode for distributing tests to exec environments.\n\n" "each: send each test to all available environments.\n\n" "load: load balance by sending any pending test to any" " available environment.\n\n" "loadscope: load balance by sending pending groups of tests in" " the same scope to any available environment.\n\n" "loadfile: load balance by sending test grouped by file" " to any available environment.\n\n" "(default) no: run tests inprocess, don't distribute." ), ``` **说明:** - `--dist=loadscope` 将按照同一个作用域方法来分组,然后将每个测试组发给可以执行的worker,确保同一个组的测试用例在同一个进程中执行 - `--dist=loadfile` 按照同一个文件名来分组,然后将每个测试组发给可以执行的worker,确保同一个组的测试用例在同一个进程中执行 - `--dist=each` 是将每个用例,分别发给所有的执行器worker,相当于开了几个执行器worker,同一个用例就执行几遍 - `--dist=load` 将待运行的用例随机发给可用的执行器worker,用例执行顺序随机的,目前默认采用这种方式 ### `--dist=loadfile` 示例: 示例代码还是上述代码,执行命令:`pytest -v -n 3 --dist=loadfile test_xdist.py test_xdist_02.py test_xdist_03.py` ![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=20210710153935297.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA0NTQxMTc=,size_16,color_FFFFFF,t_70) 结果:从结果可以看下 `gw0` 执行 `test_xdist.py` 模块, `gw1` 执行 `test_xdist_02.py` 模块, `gw2` 执行 `test_xdist_03.py` 模块 ### `--dist=loadscope` 示例: `test_xdist.py` 示例代码: ```python # !/usr/bin/python3 # _*_coding:utf-8 _*_ """" # @Time  :2021/7/10 13:31 # @Author  : king # @File   :test_xdist.py # @Software :PyCharm # @blog :https://blog.csdn.net/u010454117 # @WeChat Official Account: 【测试之路笔记】 """ import pytest import time class TestDist01: def test_01(self): time.sleep(1) print("我是 test_01 用例") assert True def test_02(self): time.sleep(1) print("我是 test_02 用例") assert True def test_03(self): time.sleep(1) print("我是 test_03 用例") assert True class TestDist02: def test_04(self): time.sleep(1) print("我是 test_04 用例") assert True def test_05(self): time.sleep(1) print("我是 test_05 用例") assert True def test_06(self): time.sleep(1) print("我是 test_06 用例") assert True class TestDist03: def test_07(self): time.sleep(1) print("我是 test_07 用例") assert True def test_08(self): time.sleep(1) print("我是 test_08 用例") assert True def test_09(self): time.sleep(1) print("我是 test_09 用例") assert True class TestDist04: def test_10(self): time.sleep(1) print("我是 test_10 用例") assert True def test_11(self): time.sleep(1) print("我是 test_11 用例") assert True def test_12(self): time.sleep(1) print("我是 test_12 用例") assert True if __name__ == '__main__': pytest.main() ``` **执行结果** 执行命令:`pytest -v -n 3 --dist=loadscope test_xdist.py` ![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=20210710155037532.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA0NTQxMTc=,size_16,color_FFFFFF,t_70) 结果:从结果可以看下 `gw0` 执行 `test_xdist.py` 模块的 `TestDist01` 和 `TestDist04` 类, `gw1` 执行 `test_xdist.py` 模块的`TestDist01` 类, `gw2` 执行 `test_xdist.py` 模块的 `TestDist03` ### `--dist=each` 示例: 与上述 `test_xdist.py` 示例代码一样,执行命令: `pytest -v -n 3 --dist=each test_xdist.py` ![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=20210710155735454.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA0NTQxMTc=,size_16,color_FFFFFF,t_70) 结果:从上面结果可以看出来,每天用例被执行了3遍 ### `--dist=load` 和 `--dist==no` 示例: - 略,前面最开始执行示例,随机将待执行的用例分别给可用的执行器worker执行 ## 总结 - 使用并行测试 加上` -n num` 或者 `-n auto` 参数即可使用 - 可以根据参数 `--dist=loadfile`、 `--dist=loadscope`、`--dist=each`、`--dist=load` 和 `--dist==no`设置不同的执行器worker执行模式 - 如果存在每条用例重复执行多次的场景,采用`--dist=each`模式,开几个执行器worker就执行几次 以上为内容纯属个人理解,如有不足,欢迎各位大神指正,转载请注明出处! >**如果觉得文章不错,欢迎关注微信公众号,微信公众号每天推送相关测试技术文章** 个人微信号:搜索 【测试之路笔记】

这篇关于pytest测试框架系列 - pytest-xdist 分布式、多进程并发执行用例你会吗?的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程