pytest提供了丰富的插件来扩展其功能,本章介绍插件pytest-order,用于自定义pytest测试用例的执行顺序。pytest-order是插件pytest-ordering的一个分支,但是pytest-ordering已经不再维护了,建议大家直接使用pytest-order。
官方文档:
https://pytest-order.readthedocs.io/en/stable/usage.html
pytest-order官方显示的python和pytest版本限制:
- pytest-order适用于 Python 3.7 - 3.12:
- 对于 Python 3.9 之前的所有版本,pytest 版本 >= 5.0.0
- 对于 Python >= 3.10,pytest >= 6.2.4。
默认情况下的执行顺序
文件间执行顺序:
pytest会首先扫描当前目录及子目录下的所有文件,查找以test_开头(或包含_test)的文件以及测试模块(如test_*.py或*_test.py)。对于找到的测试文件,它们将按照文件名的ASCII码顺序执行,即数字、大写英文字母、小写英文字母的顺序。
文件内执行顺序:
在每个测试文件中,pytest会按照测试用例(即测试函数或测试方法)定义的顺序执行。如果使用了类组织测试用例,那么类内部的测试用例将按照定义的顺序执行。
举例:测试文件中函数测试用例顺序是4,5,1,2,3,测试类中的测试用例顺序也是4,5,1,2,3。
测试用例执行后,按照4,5,1,2,3的顺序执行。
pytest-order安装
使用pip命令安装: pip install pytest-order (安装在pytest工程所运行的python环境,python的安装目录或者虚拟环境目录,可以参考之前文章查看运行环境pycharm配置pytest运行环境)
通过pycharm安装:打开设置,按照如下图中安装插件(windows系统)
pytest-order运行
使用@pytest.mark.order来装饰用例,然后执行命令中无需增加额外的运行参数,运行时会自动化识别自定义的顺序,并按照约定顺序执行。
1 使用数字定义顺序
使用正数或者负数定义顺序,数字越小先执行。举例@pytest.mark.order(1)或者@pytest.mark.order(index=1),可以直接填数字,也可以使用index=某个数字。
PS:该处的数字有点像python列表list的索引,0代表第一个元素,-1代表最后一个元素
- 如果全是正数或者全是负数,按照数字小到大的顺序执行
- 如果既有正数又有负数,则按照正数由小到大排序,然后再按照负数由小到大排序
- 没有标记的测试用例在所有具有正数标记的测试之后执行,并在具有负数标记的测试之前执行。
举例:上面的用例重新定义顺序如下,既有正数也有负数排序
预期结果是先执行函数级用例并且执行顺序是1,2,3,4,5,再执行测试类中的用例并且执行顺序是5,4,3,2,1
用例执行后结果如下:符合预期
上面的测试用例如果全部换成使用@pytest.mark.order(index=1)这种格式定义,结果也是一样,此处不在赘述
2 使用英文代表的数字定义顺序
使用英文代表的数字定义顺序,数字越小先执行。
举例@pytest.mark.order("first")或者@pytest.mark.order(index="last")
first代表第1个(相当于数字0),last代表最后1个(相当于数字-1)
如果使用不在字典中的定义会告警,举例:定义@pytest.mark.order(index="ninth"),ninth表示第9个,执行后会告警,但是不影响使用
3 在测试类上做标记
如果order在测试类上设置标记,则该类中的所有测试将被视为具有相同的序数标记,例如,整个测试类会重新排序,而不会改变测试类内的测试顺序。
举例:标记以下类顺序。
预期结果是 先执行Testcase2的test_2_1,test_2_2,然后执行Testcase1的test_1_1,test_1_2
执行结果如下:符合预期
举例:同时标记类和类内的用例顺序,以用例标记为准
预期结果是 先执行Testcase1的test_1_2,test_1_1,然后执行Testcase2的test_2_2,test_2_1
执行后结果如下:符合预期
4 相对于其他测试用例的顺序
通过标记属性before和after引用其他测试用例的名称,before表示要在引用测试用例之前执行,after表示在引用测试用例之后执行。
引用的测试用例支持如下几种情况:
1)本文件内函数级用例引用其他函数级用例
预期结果是先执行test_3,然后test_2,最后test_1
执行后结果:符合预期
2)本文件内函数级用例引用其他测试类中的用例
预期结果是先执行test_3,然后Testcse1.test_1_1,Testcse1.test_1_2,最后是test_1
执行结果如下:符合预期
3)本文件内用例引用其他文件中的用例
举例: 在同一个目录有两个测试文件test_case1.py和test_case2.py,其中test_case1.py文件中的用例通过before和after引用了test_case2.py文件中的test_1用例,
当执行这个目录的用例时,预期结果是:先执行test_case1.py.test_2,然后是test_case2.py.test_1,然后是test_case1.py.test_1,最后是test_case2.py.test_2
执行后结果: 符合预期
4)在测试类上标记其他测试类
使用before或 after标记属性来引用测试类,标记类中的测试将排在引用类中的所有测试前面或者后面。
举例:标记Testcase1类在Testcase2之后运行,并且设置Testcase2中先运行test_2_2
执行后结果:符合预期
5 绝对排序和相对排序的组合
如果将绝对顺序标记和相对顺序标记组合在一起,则首先对绝对标记(例如序数)进行排序,然后再对相对标记(before或者after)进行排序,这意味着相对顺序始终优先。
举例:设置如下两条用例,test_1_1用例标记index=1和after=’tet_1_2’,虽然设置test_1_2顺序为0,但按照相对顺序优先的原则,预期先执行test_1_2,然后再执行test_1_1。
执行结果如下:符合预期
6 同一标记的几种关系
如果需要相对于多个其他测试用例的顺序对某个测试用例进行排序,则可以使用测试名称列表或元组将多个测试名称添加到before或after参数中。
举例:设置如下4条用例,测试类Testcase.test_1_1用例标记在Testcase1.test_1_2和Testcase2.test_2_2之后执行。同时标记Testcase2.test_2_1和Testcase2.test_2_2的顺序。
如果Testcase.test_1_1不做标记,执行顺序为Testcase2.test_2_2 > Testcase2.test_2_1 > Testcase1.test_1_1 > Testcase1.test_1_2
但是标记之后,预期执行顺序是Testcase2.test_2_2 > Testcase2.test_2_1 > Testcase1.test_1_2 > Testcase1.test_1_1
执行后结果: 符合预期
7 与参数化测试的关系
1)引用被参数化的测试用例,只能使用测试名称,而不能引用某个参数。
举例:设置2条用例,test_2用例设置3个参数,而test_1标记after=’test_2’,只能标记测试用例名称。
预期是先执行3条test_2,然后再执行test_1
执行结果:符合预期
2) 在参数化用例上设置顺序标记
举例:设置2条用例,test_2用例设置3个参数并标记顺序为0
预期是先执行3条test_2,然后再执行test_1
执行结果:符合预期
8 用例上设置多个顺序标记
可以为测试设置多个顺序标记,在这种情况下,测试将按照定义的顺序执行多次。
举例:设置2条用例,test_1用例标记顺序0和1,test_2用例设置3个参数,标记两个顺序1和3,
预期是先执行 test_1,然后再执行3条test_2,再执行test_1,最后执行3条test_2
执行结果:符合预期
以上就是介绍的插件pytest-order的功能,但实际在编写测试用例时还是要尽量避免存在过多的用例的顺序依赖,如果有依赖可以参考之前文章介绍尽量使用setup或者teardown功能,总之我们要考虑尽可能减少后期维护用例的工作量。
共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”
-----指水滴不断地滴,可以滴穿石头;
-----比喻坚持不懈,集细微的力量也能成就难能的功劳。
----感谢读者的阅读和学习,谢谢大家。
---祝愿大家都能够龙腾虎跃,步步高升!!!