Pytest(16)随机执行测试用例pytest-random-order
前言
通常我们认为每个测试用例都是相互独立的,因此需要保证测试结果不依赖于测试顺序,以不同的顺序运行测试用例,可以得到相同的结果。
pytest默认运行用例的顺序是按模块和用例命名的 ASCII 编码顺序执行的,这就意味着每次运行用例的顺序都是一样的。
app 测试里面有个 monkey 测试,随机在页面点点点,不按常理的点点点能找到更多的不稳定性 bug。那么我们在写pytest用例的时候,既然每个用例都是相互独立的,
那就可以打乱用例的顺序随机执行,用到 pytest 的插件 pytest-random-order 可以实现此目的,github 地址https://github.com/jbasko/pytest-random-order
说明
pytest-random-order是一个pytest插件,用于随机化测试顺序。这对于检测通过的恰好是有用的,因为它恰好在不相关的测试之后运行,从而使系统处于良好状态。
该插件使用户可以控制要引入的随机性级别,并禁止对测试子集进行重新排序。通过传递先前测试运行中报告的种子值,可以按特定顺序重新运行测试。
快速开始
安装
pip3 install pytest-random-order
注意
从v1.0.0开始,默认情况下,此插件不再将测试随机化。要启用随机化,您必须以下列方式之一运行pytest:
pytest --random-order pytest --random-order-bucket=pytest --random-order-seed=
配置方式
如果要始终随机化测试顺序,请配置pytest。有很多方法可以做到这一点,我最喜欢的一种方法是addopts = --random-order在pytest选项(通常是[pytest]或[tool:pytest]部分)下添加特定
# pytest.ini文件内容 [pytest] addopts = --random-order
案例演示
# test_random.py def test_1(): print("用例1") def test_2(): print("用例2") def test_3(): print("用例3") # test_random2.py def test_4(): print("用例4") def test_5(): print("用例5") def test_6(): print("用例6")
执行命令
pytest -s --random-order
执行结果
Using --random-order-bucket=module Using --random-order-seed=63275 collecting ... case/random_case/test_random2.py::test_5 ✓ 17% █▋ case/random_case/test_random2.py::test_6 ✓ 33% ███▍ case/random_case/test_random2.py::test_4 ✓ 50% █████ case/random_case/test_random.py::test_3 ✓ 67% ██████▋ case/random_case/test_random.py::test_1 ✓ 83% ████████▍ case/random_case/test_random.py::test_2 ✓ 100% ██████████ Results (0.04s):
从运行的结果可以看出,默认使用--random-order-bucket=module,模块下的用例会被打乱随机执行,每次运行会重新生成--random-order-seed=63275,seed值不一样,用例的顺序也会不一样
更改重新排序与范围
要更改重新排序与范围,运行pytest --random-order-bucket=选项,其中可以是global,package,module,class,parent,grandparent:
插件组在存储桶中进行测试,在存储桶中进行混洗,然后对存储桶进行混洗,设计原理如图
给定上面的测试套件,以下是一些可能生成的测试顺序中的两个:
可以从以下几种类型的存储桶中进行选择:
class 测试将在一个类中进行混洗,而各类将被混洗,但是来自一个类的测试将永远不会在其他类或模块之间运行来自其他类的测试。
- module 模块级别。如果仅使用--random-order运行pytest,同时带上参数--random-order-seed=。
- package 程序包级别。请注意,属于package的模块(以及这些模块内的测试)x.y.z不属于package x.y,因此在对存储package桶类型进行随机分配时,它们将落入不同的存储桶中。
- parent 如果使用的是不属于任何模块的自定义测试项,则可以使用此项将测试项的重新排序限制在它们所属的父级中。对于正常测试函数,父级是声明它们的模块。
- grandparent 类似于上面的parent,但是使用测试项的父级作为bucket key。
- global 所有测试属于同一存储桶,完全随机,测试可能需要更长的时间才能运行。
- none (已弃用) 禁用混洗。自1.0.4起不推荐使用,因为此插件默认不再重做测试,因此没有禁用的功能。
如果你有测试三个桶A,B和C三个测试1和2,并3在他们每个人,那么许多潜在的排序的一个非全局随机化可以产生可能是:
c2,c1,c3,a3,a1,a2,b3,b2,b1
运行示例,带上参数--random-order-bucket=global,所有的用例都会被打乱。
Using --random-order-bucket=global Using --random-order-seed=784641 collecting ... case/random_case/test_random2.py::test_5 ✓ 17% █▋ case/random_case/test_random.py::test_3 ✓ 33% ███▍ case/random_case/test_random2.py::test_6 ✓ 50% █████ case/random_case/test_random2.py::test_4 ✓ 67% ██████▋ case/random_case/test_random.py::test_2 ✓ 83% ████████▍ case/random_case/test_random.py::test_1 ✓ 100% ██████████ Results (0.04s): 6 passed
模块或类中禁用随机
如果我们在一个模块或类中,不想让里面的用例随机,可以设置 disabled=True 来禁用随机参数
模块中禁用随机
# 写在.py文件最上面即可 import pytest pytestmark = pytest.mark.random_order(disabled=True) def test_1(): print("用例1") def test_2(): print("用例2") def test_3(): print("用例3")
类中禁用随机
import pytest class TestRandom(): pytestmark = pytest.mark.random_order(disabled=True) def test_1(self): print("用例1") def test_2(self): print("用例2") def test_3(self): print("用例3")
这样在执行的时候,TestRandom里面的用例顺序就是test_1,test_2,test_3不会被打乱
重现测试结果:--random-order-seed 随机种子
如果由于重新排序测试而发现测试失败,则可能希望能够以相同的失败顺序重新运行测试。为了允许重现测试订单,该插件报告其与伪随机数生成器一起使用的种子值:
============================= test session starts ============================== .. Using --random-order-bucket=module Using --random-order-seed=36775 ...
现在,您可以使用该--random-order-seed=...位作为下一次运行的参数以产生相同的顺序:
pytest -v --random-order-seed = 36775
禁用插件
如果你觉得这个插件不好用,或者对你的其它功能会有影响,则可以将其禁用
pytest -p no:random_order
注意
默认情况下禁用随机化。通过传递,-p no:random_order您将阻止插件的注册,因此其钩子将不会被注册,并且命令行选项也不会
- 学习pytest的第七天-----如何跳过执行测试用例
- 学习pytest的第十一天-----重复执行用例+分布式执行测试
- 【Pytest02】全网最全最新的Pytest框架快速进阶篇(pytest前置和后置以及忽略测试用例)
- Python单元测试框架之pytest---如何执行测试用例
- Pytest测试框架(一):pytest安装及用例执行
- Python之使用unittest框架和HTMLTestRunner.py文件实现多个测试用例执行与测试报告生成
- pytest文档28-重复执行用例(pytest-repeat)
- 通过Hook函数使Py.test支持含有中文的测试用例名称(nodeid)和测试报告
- 实现testng监听器统一修改用例运行次数,随机执行测试用例
- 使用testsuit执行测试用例,选择特定用例执行多次的方法(appium+python)
- 【pytest官方文档】解读Skipping test functions,跳过测试用例详解
- selenium之unittest批量执行测试用例、生成html报告
- Python-unittest---测试用例批量执行
- 学习pytest的第九天-----使用自定义的标签分类执行测试+三种生成报告的方式
- (5)unitest多用例执行及HTMLTestReport测试报告应用
- 1个练习引发的系列学习之pytest指定测试用例 (二)
- Python中unittest测试用例的执行顺序问题
- 2-3 随机生成算法测试用例-Selection-Sort-Generate-Test-Cases
- selenium---unittest框架测试用例函数执行顺序 优先级
- python利用unittest进行测试用例执行的几种方式