pytest简易教程汇总,详见:https://www.cnblogs.com/uncleyong/p/17982846
为什么要写pytest?
之前分享了java自动(详见:https://www.cnblogs.com/uncleyong/p/15867903.html),
部分测友建议分享一个python版本自动化,
而pytest这个热门单元测试框架作为python自动化中的必备技术栈,必须单独拎出来详解。
后续分享基于pytest最新版,和老版本有微小差异。
pytest介绍
官网:https://www.osgeo.cn/pytest/contents.html
pytest是python语言下的一种单元测试框架,与python自带的unittest单元测试框架类似,相比于unittest框架使用起来更简洁,效率更高。
(补充:java语言下的单元测试框架是junit和testng)
pytest可以结合requests实现接口测试,结合selenium/playwright、appium实现自动化功能测试。
pytest特点:
1.具有unittest绝大部分功能,非常容易上手,入门简单,功能灵活,文档丰富,文档中有很多实例可以参考
2.具有强大灵活的fixture固件,支持简单的单元测试和复杂的功能测试;
3.支持参数化(parametrize)、数据驱动
4.执行测试过程中可以将某些测试跳过(skip),或者对某些预期失败的case标记成失败(xfail)
5.支持重复执行(rerun)失败的case
6.支持运行由nose ,unittest编写的测试case
7.支持执行部分用例(比如:根据标记,或者features、stories,后者一来allure-pytest插件)
8.具有很多第三方插件(顺序控制pytest-ordering、allure报告allure-pytest、多线程pytest-xdist、......),并且可以自定义开发插件
9.可生成html报告,也可以结合allure生成精美的测试报告
10.方便的和持续集成工具jenkins集成
和unittest区别:
不同点 | unittest | pytest |
命名 | 测试方法以test开头 | 模块名必须以test_开头,或者_test结尾 类以Test开头 方法/函数以test开头 |
框架结构 | 写case必须定义类,测试类要继承unitttest.TestCase | 不需要继承,可以是函数也可以是类中方法 |
测试报告 | 使用HTMLTestRunner | 使用allure-pytest |
数据驱动 | 参数化使用第三方ddt | 参数化使用自带的parametrize |
断言 | 断言库丰富 | 采用python断言:使用assert关键字 |
失败重试 | 不支持 | 支持 |
固件 | - | 灵活的fixture固件 |
扩展性 | - | 快速自定义插件开发 |
pytest测试用例编写规则
类型 | 规则 |
模块 | 模块名必须以test_开头,也就是:test_*.py 或者_test结尾,也就是:*_test.py 建议:test_+业务名称 |
类 | 测试类类名以Test开头 说明:测试类中不能包含__init__构造方法,添加构造方法后就不是测试类了,里面的测试方法都识别不到 |
方法/函数 | 以test开头 |
包 | 包名无特殊要求 包必项要有__init__.py文件 |
安装pytest
前提:已经安装、配置python环境
参考:https://www.cnblogs.com/uncleyong/p/10778792.html
通过命令安装
安装命令:pip install pytest
如果安装不了,请更换pip源,参考:https://www.cnblogs.com/uncleyong/p/17997261
如果已经安装,升级到最新版本:pip install -U pytest
通过pycharm安装
pycharm中安装需要的包,在settings中,选择Python Interpreter,然后点击“+”
搜索要安装的包,右下角可以选择需要的版本,最后左下角安装即可
验证是否安装成功
pycharm默认测试执行器
settings中,进入Tools -> Python Intergrated Tools,Default test runner默认是自动发现的,可以直接选择pytest
也可以settings中搜索pytest快速进入Python Intergrated Tools
第一个示例
test_qzcsbj.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : 韧
# @wx :ren168632201
# @Blog :https://www.cnblogs.com/uncleyong/
def inc(x):
return x + 1
def test_a():
print("---test_a")
assert inc(0) == 1
class TestCase:
def test_b(self):
print("---test_b")
assert "cs" in "qzcsbj"
pycharm中运行
左侧有绿色执行按钮
点击绿色按钮,用的pytest解释器执行的,而不是python解释器
结果(pycharm中执行,选中“√”才展示所有测试方法)
一次执行模块中所有方法
1、可以非测试方法处点右键执行
2、也可以用main方法运行:调用pytest的main函数执行测试,需要import pytest
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : 韧
# @wx :ren168632201
# @Blog :https://www.cnblogs.com/uncleyong/
import pytest
def inc(x):
return x + 1
def test_a():
print("---test_a")
assert inc(0) == 1
class TestCase:
def test_b(self):
print("---test_b")
assert "cs" in "qzcsbj"
if __name__ == '__main__':
pytest.main()
pytest.main()等价于pytest.main(["./"]),运行当前目录下的所有用例
点击main左侧绿色按钮结果
补充:
如果放到vscode中,会执行工程下所有用例,只运行当前模块的用例,需要加参数__file__,表示当前文件
if __name__ == '__main__':
pytest.main([__file__])
命令运行
注:此时用例文件中有main方法,把main方法注释掉
进入项目目录,执行pytest
test_a改为失败,一个成功一个失败,成功是.,失败是F
pytest等价于python -m pytest
但是,
如果没有main方法,执行python case\test_qzcsbj.py,下面没有结果
如果有main方法
执行python case\test_qzcsbj.py,就有结果
总结
- 用pytest的解释器执行用例:1、命令行中直接执行pytest;2、pycharm中方法和类,直接点绿色执行按钮运行;模块和包,选中模块或者包,然后右键运行;或者非测试方法处点右键执行(因为pycharm已设置默认测试执行器是pytest)
- 用python的解释器执行用例:1、命令中执行python -m pytest调用pytest(jenkins持续集成可用到,可指定不同版本的python);2、有main函数,命令中执行python xxx.py,调用py文件中main函数中的pytest.main();说明:直接执行这个模块,被执行的模块是main(可print(__name__)查看结果),如果此模块被其它模块导入,这个模块就不是main了。
主要命令参数
参数 | 说明 |
--help | 查看帮助,等同-h |
-q | 简化控制台的输出,只输出执行结果,几条用例通过或不通过 |
-v | 详细输出,打印详细日志,可以看到用例执行的先后顺序、结果;如果不加-v,成功看到的是绿色.,失败看到的是红色F |
-s | 调试输出,就是输出print的内容,等价于pytest --capture=no,可以捕获print函数的输出 一般和-v一起用,-vs |
-k | 测试方法名中包含指定关键字的测试用例,支持and、or、not 比如: pytest -k test_2,或者pytest -k "test_2" pytest -k "test_2 or test_1",这里要用双引号 pytest -k "not test_1" |
-m | 通过标志表达式运行 比如:pytest -m user,pytest -m "user",将运行 @pytest.mark.user装饰器修饰的所有用例 等价main中,pytest.main(["-m","user"]),一般加上-vs,pytest.main(["-vs","-m","user"]) |
-n=2 | 多线程运行(依赖于插件) |
-x | 用例一旦失败(fail/error)就立即停止测试(相当于冒烟测试,失败就停止,哪怕没执行完,也不用关心后面的执行结果),等价于pytest --exitfirst |
--maxfail=n | 在第n次失败后停止测试,也就是失败数达到num就停止 |
--lf | 重跑上次失败用例,等价于--last-failed;命令行参数使用缓存状态 如果这些失败的都成功了,再次运行,会把所有成功的都运行,而不是没有失败的了就不运行了 |
--collect-only | 收集测试用例(不执行) |
-h参数
pytest -h的结果分类:
1. 命令行参数
用于pytest运行时的参数,比如-k、-m等,有通用类、报告类、收集类、调试类、日志类等
通用类
报告类
告警
收集
调试
日志
2. 元数据
3.配置参数:pytest.ini中配置的参数
4.环境变量
5.重跑失败
-s参数
示例:上面示例发现,如果用例执行成功,print内容没显示,可以加-s参数捕获print函数的输出
其它参数用法,后续篇幅通过示例演示。