本文首发于:行者AI
Pytest是Python的一种单元测试框架,与unittest相比,应用起来更简洁、效率更高,也是目前大部分应用python编写测试用例的小伙伴们的第一抉择了。
除了框架自身提供的性能外,Pytest还反对上百种第三方插件,良好的扩展性能够更好的满足大家在用例设计时的不同需要。本文将为大家具体介绍上面5项罕用的插件。
1. 用例依赖
编写用例的时候,咱们会留神用例之间的独立性,但局部用例之间的确存在关联,无奈做到彻底独立,那么咱们就能够通过应用插件pytest-dependency设置用例之间的依赖关系。当用例A依赖于用例B时,若用例B执行失败,则用例A将会主动跳过不执行。如此,就能够防止去执行一个必定会失败的用例,相当于pytest.mark.skip。
(1)装置:
pip install pytest-dependency
(2)应用阐明:
首先,在标记被依赖用例时,须要在被依赖的用例上增加装璜器pytest.mark.dependency(),且被依赖用例须要在关联用例前执行。也能够给被依赖用例设置别名,通过增加参数name实现。
在关联的依赖用例上,同样须要增加装璜器pytest.mark.dependency(depends=['用例名称']),与之前不同的是,装璜器必须要填写depends参数实现用例的关联,关联的被依赖用例存在多个时能够应用“,”隔开。
此外,还能够通过scope参数指定用例依赖的范畴,同样是session、package、module、class这四种类型,此处不具体开展。
具体通过下方的示例以及执行后果来进一步阐明。
(3)示例及执行后果剖析
示例:
import pytestclass TestCase: # 通过装璜器@pytest.mark.dependency()标记以后用例为被依赖用例,被依赖用例须要优先关联用例执行 @pytest.mark.dependency() def test_01(self): print("测试用例01,执行失败") assert 1 == 2 # 通过应用装璜器关联被依赖用例,通过depends参数指定用例名称关联用例 @pytest.mark.dependency(depends=['test_01']) def test_02(self): print("测试用例02,跳过") # 标记被依赖用例时,能够通过name参数指定别名 @pytest.mark.dependency(name="func_2") def test_03(self): print("测试用例03,执行胜利!") # 应用depends参数指定定义的别名关联用例 @pytest.mark.dependency(depends=['func_2']) def test_04(self): print("测试用例04,执行胜利!") # depends参数能够关联多个测试用例,应用“,”分隔即可 @pytest.mark.dependency(depends=['test_01', 'func_2']) def test_05(self): print("测试用例05,跳过")if __name__ == '__main__': pytest.main(['-vs'])
执行后果如下:
咱们能够看出,只有依赖用例执行胜利时,以后用例才会被执行,否则会被跳过。依赖多个用例时,只有全副胜利,才会执行,否则一样会跳过。
2. 失败重跑
有些状况下,用例在执行过程中可能会受到一些客观因素的影响,导致用例执行失败,通过应用pytest-rerunfailures插件,能够在失败后从新执行用例,并设置从新运行的最大次数。以此保障用例执行后果的准确性。
(1)装置:
pip install pytest-rerunfailures
(2)应用阐明:
失败重跑共有两种应用形式,别离是通过装璜器执行和命令行执行。
应用装璜器时,须要在用例上增加装璜器pytest.mark.flaky(reruns=从新执行最大次数, reruns_delay=执行间隔时间(单位:秒)),在执行过程中,增加了装璜器的用例在执行失败后会依照设置的次数和工夫从新执行。
通过在命令行执行时,同样须要指定"rerun"和"rerun-delay"两个参数来实现,如:pytest --reruns 从新执行最大次数 --reruns-delay 间隔时间。
留神:reruns是从新执行的最大次数,如果在达到这一数量前用例执行胜利,则不会持续重跑,判断用例执行通过;否则执行到最大次数后,用例仍失败,则判断用例执行失败。
具体通过下方的示例和执行后果进一步阐明。
(3)示例及执行后果剖析
示例:
import pytestimport randomclass TestCase: # 应用装璜器设置用例失败后的从新执行最大次数和每次执行的间隔时间(单位:秒) @pytest.mark.flaky(reruns=3, reruns_delay=1) def test_01(self): result = random.choice(['a', 'b', 'c', 'd', 'e']) print(f"result={result}") assert result == 'c'if __name__ == '__main__': pytest.main(['-vs'])
执行后果如下:
咱们能够看出,当用例断言失败后,会从新执行,直到达到设置的最大次数或执行胜利为止。
3. 指定用例执行程序
pytest在执行用例的时候,默认是依照文件中用例的先后顺序执行,有时咱们可能在保护测试用例时遇到须要批改用例执行程序的状况,然而如果每次都通过批改大段的用例代码先后地位来管制,并不利于保护。因而,应用插件pytest-ordering能够疾速实现用例执行程序的设置,前期保护时,也只须要批改对应的执行程序参数即可。
(1)装置:
pip install pytest-ordering
(2)应用阐明:
通过给用例增加装璜器pytest.mark.run(order=执行程序)设置用例的执行程序。在执行的时候,应用装璜器pytest.mark.run的用例会优先没有装璜器的用例执行,设置了执行程序的用例则依照order参数设置的大小升序执行。
具体通过下方的示例和执行后果进一步阐明。
(3)示例及执行后果剖析
示例:
import pytestclass TestCase: def test_01(self): print("测试用例01") def test_02(self): print("测试用例02") # 应用装璜器设置执行程序为2 @pytest.mark.run(order=2) def test_03(self): print("测试用例03") # 应用装璜器设置执行程序为1 @pytest.mark.run(order=1) def test_04(self): print("测试用例04")if __name__ == "__main__": pytest.main(['-vs'])
执行后果:
咱们能够看出,执行的程序和预期统一。优先执行表明了执行程序的用例,并依照order的值由小到大执行。
4. 分布式运行
当我的项目的用例很多的时候,执行通常会耗时颇久,通过分布式运行,则能够大量缩短整体用例的执行工夫。pytest-xdist插件就能够帮忙咱们实现测试用例的分布式运行。
(1)装置:
pip install pytest-xdist
(2)应用阐明:
在命令行执行用例时,通过参数-n设置并行启动的过程数量。除了设置具体的数量外,还能够设置为auto,这种状况下,会根据以后设施的cpu数量执行。
此外,还能够通过--dist参数,设置用例分组,同一个组内的用例会在同一个过程中执行。
- --dist=loadscope 同一个module或同一个class下的用例会调配为同一组,按class分组优先于module。
- --dist=loadfile 同一个.py文件中的用例会调配为同一组。
具体通过下方的示例和执行后果进一步阐明。
(3)示例及执行后果剖析
示例:
import pytestfrom time import sleepclass TestCase1: @pytest.mark.parametrize('keyword', ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']) def test_baidu_search(self, keyword): sleep(1) print(f'搜寻关键字{keyword}')class TestCase2: @pytest.mark.parametrize('user', ['user1', 'user2', 'user3', 'user4', 'user5', 'user6', 'user7', 'user8', 'user9', 'user10']) def test_login(self, user): sleep(1) print(f'用户{user}登录胜利')if __name__ == '__main__': # pytest.main(['-vs']) # 不应用pytest-xdist运行 pytest.main(['-vs', '-n', '2']) # 应用pytest-xdist运行
执行后果:
从上方的两次执行后果中能够看出,应用分布式运行后,用例的运行工夫显著缩短。示例中的用例彼此之间没有关联,如果理论应用时用例之间存在依赖关系,能够应用--dist参数为用例分组,确保关联的用例在同一组内。
5. 多重断言
有时,在一个用例中,咱们须要对后果进行不同维度的多个断言,然而应用assert断言时,只有有一个断言失败,后续的断言就不会继续执行。当初,咱们能够通过应用pytest-assume插件来解决这个问题,当断言失败后,仍会继续执行后续的断言。
(1)装置:
pip install pytest-assume
(2)应用阐明:
在用例中,把应用assert进行的断言,改为应用pytest.assume()进行断言即可。
具体通过下方的示例和执行后果进一步阐明。
(3)示例及执行后果剖析
示例:
import pytestclass TestCase: # 应用assert断言 def test_01(self): print("断言1") assert 1 == 1 print('断言2') assert 2 == 1 print("断言3") assert 3 == 3 print('用例完结') # 应用pytest.assume()断言 def test_02(self): print('断言1') pytest.assume(1 == 1) print('断言2') pytest.assume(2 == 1) print('断言3') pytest.assume(3 == 3) print('用例完结')if __name__ == '__main__': pytest.main(['-vs'])
执行后果:
从执行后果中能够看出,应用assert断言时,断言失败不会再执行后续的内容;而应用pytest.assume()断言时,断言失败仍会执行至用例完结。这样更有利于咱们一次性获取用例执行中全副错误信息。
6. 小结
本文为大家介绍了一些罕用的pytest框架的插件,能够帮忙咱们解决一些理论应用过程中遇到的问题。目前,pytest反对的插件曾经多达868个,除了本文介绍的5个罕用插件外,还有很多反对其它需要的插件,大家能够依据本人的须要尝试查找应用相干的插件,以便可能更好的设计出合乎业务场景的测试用例。