一、pytest框架简介
- pytest是单元测试框架(测试函数、方法)
- 自动化测试框架的功能:发现用例 —> 执行用例 —> 判断结果 —> 输出结果
- pytest框架 < 单元测试框架 < 自动化测试框架
- pytest+插件/包:
- requests:接口自动化
- selenium、appium:UI自动化
- allure-pytest:美观的测试报告
- Jenkins:持续集成
- pytest-html:生成HTML格式的报告
- pytest-xdist:分布式执行
- pytest-ordering:更改执行顺序
- pytest-rerunfailures:重跑失败用例
二、pytest测试用例命名规则
- 模块(.py文件)名必须以test_开头或以_test结尾;
- 类名必须以Test开头,且不能有init方法;
- 方法名必须以test开头;
三、pytest运行方法
1. 主函数模式:
-
运行所有用例:
pytest.main([“-vs”])
主函数在任何一个py文件中,都能执行同目录及以下所有py文件中的用例
-
指定目录(文件夹名):
pytest.main(["-vs", "login"])
-
指定模块(.py文件):
pytest.main(["-vs", "login/test_login.py"])
-
指定方法(nodid,::作为隔离符 ):
pytest.main(["-vs", "login/test_login.py::TestLogin::testLogin"])
2. 命令行模式:
- 参考主函数运行模式
3. 通过读取pytest.ini配置文件运行(实际工作中最常使用)
- pytest.ini:pytest核心配置文件
- 位置:一般在项目根目录
- 编码:ANSI
- 作用:改变pytest的默认行为,运行pytest前都会去读取此文件
[pytest]
addopts = -vs
# 命令行的参数
testpaths = ./test
#测试用例的路径
python_files = yqsl_*.py
# 测试模块名规则
python_classes = Yqsl*
# 测试类名规则
python_functions = yqsl*
#测试方法名规则
markers =
# 运行哪些标记用例
参数详解:
-vs
:输出更详细的信息 + 输出调试信息(包括print打印信息)
-n 数量
:分布式运行,pytest.main(["-vs", "test_login.py", "-n=2"])
-x
:用例报错即停止测试
--maxfail 数量
:报错达到最大数量才停止测试,pytest.main(["-vs", "test_login.py", "--maxfail=2")
--reruns 数量
:失败的用例重跑次数,pytest.main(["-vs", "test_login.py", "--reruns=2"])
-k
:用例名称模糊匹配后执行,pytest.main(["-vs", "test_login.py", "-k=login''])
--html ./report/report.html
:生成HTML格式报告
四、pytest执行顺序
- 默认从上到下执行
- 可以使用
mark
标记来更改顺序:@pytest.mark.run(order=1)
提示:必须先安装pytest-ordering
插件
五、分组执行
pytest
中用markers
标记用例,可以指定执行标记用例(如:测试模块,用户管理模块)- 代码中用
@pytest.mark.xxx
给用例打上标记 pytest -vs -m "xxx or xxx"
:使用命令行方式执行时
六、跳过部分用例执行
1. 无条件跳过
@pytest.mark.skip(reason="跳过原因")
1. 有条件跳过
@pytest.mark.skipif(age>=18, reason="跳过原因")
变量age
大于18
时,跳过执行此用例
七、前后置(夹具),常用的有三种
-
setup
、teardown
(setup_class
、teardown_class
)def setup_class(self):
# 这个在所有用例执行前执行一遍def setup(self):
# 这个在每个用例执行前执行一遍def teardown(self):
# 这个在每个用例执行后执行一遍def teardown_class(self):
# 这个在所有用例执行后执行一遍
缺点:如果一个测试类下部分用例要执行夹具(如:打开浏览器),则不能实现
-
@pytest.fixture(scope="", params="", autouse="", ids="", name="")
scope
表示被标记方法的作用域(function(默认)
、class
、module
、package/session
)params
参数化:- 支持列表
[]
、元祖()
、字典列表[{}, {}, {}]
、字典元祖({}, {}, {})
- 如果有多个参数,被标记的方法则会执行多次
- 支持列表
autouse=Ture
类下所有用例执行前自动添加夹具方法(无需给每个用例都引用夹具名称),默认是false
。ids
当使用params
时给每一个值设置一个变量名。意义不大name
给被标记的方法取一个别名
-
conftest.py
- 单独用于存放fixture的配置文件
conftest.py
中的固件在使用时不需要引用- 可以有多个
conftest.py
文件 - 用例中先引用的固件,则先执行
八、处理全局、中间变量
- 比较成熟的方式是:通过一个yaml文件管理(接口框架封装第一步)
- 通过一个范围是session的fixture来调用clear_yaml。保证每次session之前都清楚yaml文件内容
九、断言
- 一般断言方式:
assert xxx in response
assert response["body"] == xxx
十、结合allure-pytest生成报告
-
前提安装插件、包:
- 官网下载并解压allure到目录;
- 将allure/bin目录添加到全局配置path中;
- 验证安装成功
allure --version;
pip list
中安装allure-pytest
插件;
-
报告生成流程:
- 生成临时的json文件:
- pytest.ini中添加命令:
addopts=-vs --alluredir ./temp
- pytest.ini中添加命令:
- 通过json文件生成allure报告:
- 命令:
os.system(allure generate ./temp -o ./reports --clean)
- 解释:
allure generate ./temp
:生成allure
报告,从./temp
目录中读取临时json
文件;-O ./reports
:输出结果到./reports
目录下;clean
:输出前清除上一次的数据;
- 命令:
- 生成临时的json文件:
十一、使用yaml实现数据驱动
-
使用
@fixture.mark.parametrize(args_name, args_value)
完成args_name
:参数名(多个参数名,则可以解包。如"name1, value1"
)args_value
:参数值(支持列表[]
、元祖()
、字典列表[{}, {}, {}]
、字典元祖({}, {}, {})
,如果有多个参数,被标记的方法则会执行多次) -
举例:
@fixture.mark.parametrize("name, value", [["张三", 18], ["李四", 20]])