单元测试工具Pytest常用插件总结
发布于 2021-05-09 23:57 ,所属分类:软件测试工程师学习资料

出品|51Testing软件测试网


对于我们测试人来说,目前用到的最多的单元测试工具非pytest莫属。pytest本身已经给我们提供了很多功能了,但是如果结合它的第三方插件,那么pytest才是真正的属于我们测试编写自动化用例的强大工具。
今天安静就带大家来认识下pytest中的一些常用插件。


都说pytest比unittest好,那么具体好到哪些地方呢?这不就来了。
unittest和pytest目前本身框架中不支持用例失败重跑,但是pytest有强大的第三方插件: pytest-rerunfailures。
pytest-rerunfailures属于pytest的第三方插件,用来做测试用例失败后进行重新执行。
安装:
pip install pytest-rerunfailures源码:
https://github.com/pytest-dev/pytest-rerunfailures
官方文档:
https://pypi.org/project/pytest-rerunfailures/
使用方法:
pytest-rerunfailures的使用方法有两种,安静拿实例具体演示。
方法一:装饰器
通过装饰器的方法来标记测试用例,当标记过的测试用例执行失败后,则重新进行执行。
@pytest.mark.flaky(reruns=3, reruns_delay=2)# reruns =3:表示用例失败后需要重新执行几次,数字可以根据项目进行改变# reruns_delay=2:表示用例失败后等待几秒再重新执行,数字可以根据项目进行改变
(左右滑动查看完整代码)
装饰器不仅仅在单独的用例中使用,还能在单独的测试类中进行执行。
装饰器在用例上:
这里安静通过随机值进行确定测试用例会存在失败,从而进行重新跑。
import pytestimport randomclass Test01:@pytest.mark.flaky(reruns=3, reruns_delay=2)def test_01(self):a = random.randint(0, 3)print('---用例01---')print(a)assert a == 2def test_02(self):print('---用例02---')assert 1 == 1if __name__ == '__main__':pytest.main(['-vs'])
(左右滑动查看完整代码)
通过下图可以看到,我们执行用例1一共执行了3次,第一次设置的随机值为1和断言2不一致,进行重新跑,第2次随机值为0和断言2也不一样,第3次的时候断言相同了,用例通过:

装饰器在类上:
import pytestimport random@pytest.mark.flaky(reruns=3, reruns_delay=2)class Test01:def test_01(self):a = random.randint(0, 2)print('---用例01---')print('用例01中的a:%s'%a)assert a == 2def test_02(self):c = random.randint(0, 2)print('---用例02---')print('用例02中的c:%s'%c)assert c == 1if __name__ == '__main__':pytest.main(['-vs'])
(左右滑动查看完整代码)
通过下方执行结果可以很清楚的看到,我们class下的用例都进行了失败重跑。

方法二:命令行
pytest-rerunfailures也可以通过命令行进行执行。
方式一:pytest --reruns 3 --reruns-delay 2方式二:pytest -vs --reruns=3 --reruns-delay=2# reruns:失败重新运行次数# rerun-delay:表示失败后等待多少秒后重新执行
(左右滑动查看完整代码)
继续用上面的例子进行演示:
import pytestimport randomclass Test01:def test_01(self):a = random.randint(0, 2)print('---用例01---')print('用例01中的a:%s'%a)assert a == 2def test_02(self):c = random.randint(0, 2)print('---用例02---')print('用例02中的c:%s'%c)assert c == 1if __name__ == '__main__':pytest.main(['-vs'])
(左右滑动查看完整代码)
打开cmd终端,进入到测试用例的目录中然后输入命令进行执行。

好了,失败重跑就这么多的知识,是不是很简单、很方便?这里安静提一句,装饰器的方法和命令行的方法不能同时使用,不然会报错的。


我们还是拿unittest和pytest来比较,unittest中的执行顺序是通过ASCll值排列方式来执行的,pytest是通过用例编写的先后顺序来执行的。
当在特点的场景下需要制定执行用例的顺序,如果按照以前的方法只能更改用例的名称来完成,但是pytest中的插件pytest-ordering来控制用例的执行顺序。
pytest-ordering属于pytest的第三方插件,用来控制pytest用例的执行顺序。
安装:
pip install pytest-ordering源码:
https://github.com/ftobia/pytest-ordering
官方文档:
https://pypi.org/project/pytest-ordering/
使用方法:通过装饰器进行标记用例。
@pytest.mark.run(order=X)# x:表示执行顺序
(左右滑动查看完整代码)
具体案例:
import pytestclass Test01():@pytest.mark.run(order=3)def test_02(self):print('\n---用例02---')@pytest.mark.run(order=2)def test_01(self):print('\n---用例01---')@pytest.mark.run(order=1)def test_03(self):print('\n---用例03---')if __name__ == '__main__':pytest.main(['-vs'])
(左右滑动查看完整代码)
通过执行已经可以看出来按照我们的标记的顺序进行执行了。

这里大家也有注意的点,如果未标记的和标记的同时执行时,执行的顺序,先执行标记的,后按照编写顺序执行。


在我们执行测试用例时候,如果用例较多的话,可能会导致执行的速度过长。这时是否可以考虑下可不可以将用例并行进行测试?
其实方法是有的既然这里介绍的是pytest的插件,那么我们就通过pytest中的pytest-xdist的方法进行完成分布式执行。
pytest-xdist:表示在测试过程中可以使我们的测试用例一起并行测试,运行情况是根据你运行环境存在的CPU个数,运行过程中进行组合测试运行,从而加快我们的测试时间。
当我们在使用pytest-xdist时候,对编写的用例有一定的要求:
一定保证用例的独立性,用例之间互不影响;
一定保证用例的随机性,执行用例不能存在特定的顺序;
一定保证用例的重复性,每条用例的执行结果不影响到其他的用例。
安装:
pip install pytest-xdist官方地址:
https://pypi.org/project/pytest-xdist/
使用方法:
pytest -n 2# 其中后面的数字表示启动几个cpu来执行用例pytest -n auto# 其中auto表示启动当前系统的最大可用cpu数量
(左右滑动查看完整代码)
这里安静简单的举个例子给大家展示:
import pytestimport timeclass TestCase:def test_01(self):time.sleep(2)print('---测试用例01---')def test_02(self):time.sleep(2)print('---测试用例02---')def test_03(self):time.sleep(2)print('---测试用例03---')def test_04(self):time.sleep(2)print('---测试用例04---')assert 1 == 1if __name__ == '__main__':pytest.main(['-vs'])
(左右滑动查看完整代码)
上述代码中的time加了延迟是为了和后面进行分布式执行时方便对比执行时间。

这里发现执行结果用了8.07s的时间。那么当我们加上分布式并且加上2个cpu时,查看下执行速度,已经加快了3秒钟。

那么当我们调用电脑的最大cpu数量呢?这个执行速度已经达到了3.93秒。速度提高了很多。



在编写自动化测试用例的时候,可能一条用例存在这多条断言,那么在自动化中如何编写多条断言且断言失败后还能继续往下执行?这里引入新的插件pytest-assume。
pytest-assume:属于pytest的插件,可以在用例中使用多个断言,且断言时候后不影响其他的断言。
安装:
pip install pytest-assume源码:
https://github.com/astraw38/pytest-assume
使用方法和普通的断言方式一样,唯一区别就是断言失败后,可以继续执行。
import pytestclass Test_01:def test_01(self):print('---用例01---')pytest.assume('anjing' in 'test_anjing')pytest.assume(1==2)print('执行完成!')def test_02(self):print('---用例02---')def test_03(self):print('---用例03---')if __name__ == '__main__':pytest.main(['-vs'])
(左右滑动查看完整代码)
通过执行结果可以看出来,在第2个断言失败后,又继续执行下面的操作了。



编写测试用例之间讲究独立性,那么如果用例之间无法做到独立性,当第1个用例失败的时候与其存在依赖关系的用例也随之失败,那么这个时候有没有什么办法可以将当用例失败后,与其有依赖关系的用例将其不执行。
pytest中的插件pytest-dependency将完美的解决了这个问题。
pytest-dependency:属于pytest的插件,用来标记用例之间的依赖关系。
安装:
pip install pytest-dependency源码:
https://github.com/RKrahl/pytest-dependency
使用方法:
import pytestclass TestCase:@pytest.mark.dependency()def test_01(self):print('测试用例01')assert 1 == 2@pytest.mark.dependency(depends='test_01')def test_02(self):print('测试用例02依赖测试用例01')@pytest.mark.dependency(name='test')def test_03(self):print('测试用例03')assert 1==1@pytest.mark.dependency(depends=['test'])def test_04(self):print('测试用例04依赖测试用例03')if __name__ == '__main__':pytest.main(['-vs'])
(左右滑动查看完整代码)
上述代码中提供了2种使用方法,一种之间通过装饰器@pytest.mark.dependency()的方法进行使用,另一种进行创建新的名字进行使用。
通过上述代码中也可以看到,用例2依赖于用例1,用例4依赖于用例3。通过执行,发现会有1个失败,2个成功和1个跳过。跳过的用例正是用例2,依赖的用例1失败了。



自动化测试完成后都会有一份详细的测试报告,作为目前最火的pytest单元测试框架,当然也有测试报告,测试报告是通过pytest的插件-pytest-html进行完成的。
pytest-html:属于pytest的第三方插件,用来生成测试报告。
安装:
pip install pytest-html源码:
https://github.com/pytest-dev/pytest-html
使用方法:
直接在命令行参数中加入pytest--html=report.html其中report.html表示生成的报告文件名称。
import pytestclass TestCase:def test_01(self):print('\n测试用例01')def test_02(self):print('\n测试用例02')@pytest.mark.skip()def test_03(self):print('\n测试用例03,跳过的测试用例')def test_04(self):print('\n测试用例04,失败的测试用例')assert Falseif __name__ == '__main__':pytest.main(['-vs'])
(左右滑动查看完整代码)
可以从上图代码中看出,用例1和2是正常通过的,用例3是跳过的,用例4是失败的用例,分别通过这些用例查看在报告中的显示情况。
在命令行中输入pytest --html=report.html,然后会在当前目录中生成一个report.html的文件,打开后就是下图的内容。



出去面试的经常问到自动化测试用例的覆盖率是多少?达到100%了吗?这个问题对于我们的pytest来说也存在一个插件pytest-cov。
pytest-cov:属于pytest的第三方插件,常用来做单元测试的覆盖率。
安装:
pip install pytest-cov源码:
https://github.com/pytest-dev/pytest-cov
使用方法:
这里安静只是列举出来如何使用,没有拿具体的实例进行测试。
class TestCase:def test_01(self):print('---测试用例01---')def test_02(self):print('---测试用例02---')def test_03(self):print('---测试用例03---')def test_04(self):print('---测试用例04---')assert 1 == 1
(左右滑动查看完整代码)
在终端中通过输入命令pytest --cov进行覆盖率的结果,通过下图可以看出来,单元测试覆盖率只有10%,执行率是100%。



上述介绍了一些pytest常用的插件信息,那么当我们编写程序时候,需要一个个安装比较麻烦,这里安静介绍一个快捷安装需要库的方式。
在项目的根目录中创建requirements.txt的文件,将需要依赖的库全部都写入到文件中。

在根目录中通过终端打开,输入pip install -r requirements.txt这样的话就可以将我们所依赖的所有库都一起装入了。



安静简单的介绍了关于pytest的常用插件,这些插件对于我们执行自动化测试用例,以及编写测试用例都有非常好的作用。但是具体如何实践到公司的项目中,这个就要看大家如何使用了。

点击阅读☞接口自动化核心知识点浓缩,为面试加分!
点击阅读☞惊呆,原来QA需要具备这么多能力
点击阅读☞新人如何做好功能测试,看这几点就够了
点击阅读☞211本科大佬的真实面试经历:测试人要不要去外包公司?
点击阅读☞2020年应聘华为测试岗三轮面试经历分享
























![[HTML5] 大量HTML+CSS等网页设计前台工具使用视频合集 各种常用工具讲解视频 Python学习资料](https://static.kouhao8.com/sucaidashi/xkbb/f92302223e898c5322460e8eaad3a5ac.jpg?x-oss-process=image/format,webp/resize,w_88/crop,w_88,h_88,g_nw)

![[UI设计] 多套AI设计视频精华总结篇 视频+工具AI教程入门到精通包含PC版+MAC版工具](https://static.kouhao8.com/sucaidashi/xkbb/ed8d546a34102dd103bcc85163afad12.jpg?x-oss-process=image/format,webp/resize,w_88/crop,w_88,h_88,g_nw)


![[Python] 编程培训班推荐 学生python编程开始学习工具包 全套安装程序 插件环境 融入式学习](https://static.kouhao8.com/sucaidashi/xkbb/ea8bf1e8ef7957e6802322d8ef7b4782.jpg?x-oss-process=image/format,webp/resize,w_88/crop,w_88,h_88,g_nw)
相关资源