目录
前言
一、基本流程
二、默认用例规则
三、运行方式
四、pytest.ini配置
五、fixture(重点)
六、参数化
总结
前言
该文章只记录学习过程使用到的方法,仅供参考
一、基本流程
1、pytest_configure:初始化阶段,测试配置文件初始化(如conftest.py)
2、pytest_sessionstart:启动阶段,启动测试会话
3、pytest_collection:收集阶段,根据实际设置的条件收集测试用例
4、pytest_runtestloop:执行阶段,执行收集到的测试用例
5、pytest_sessionfinish:结束阶段,结束测试会话
6、pytest_unconfigure:暂时不了解
二、默认用例规则
1、测试用例函数命名必须以test_开头
2、测试用例所在类命名必须以Test开头,且不能有init方法
3、测试用例所在文件命名必须以test_开头或_test结尾,风格建议统一
【注】上述规则均可在pytest.ini文件中修改
三、运行方式
1、终端运行(常用于调试)(项目根目录下):
pytest -s test_case/test_01.py
2、 脚本内运行(主函数文件下)
if __name__ == '__main__': ? ? pytest.main(['-s','test_case/test_01.py'])
3、pytest参数
- -s:显示标准输出,可打印测试用例中的print内容
- -v:显示报告详细内容,如每个用例执行结果
- -q:显示报告简介内容,如整个测试会话执行结果
- -m:标记,执行打标记的用例,可以通过and、or进行逻辑判断,如'test1 and test2'
- --strict:禁止使用配置文件(如pytest.ini)未注册的标记,如果有则跳过执行阶段
- 文件/目录名:位置参数,需要执行的测试用例文件或文件所在目录
- --count:重复执行测试用例的次数,需要提前安装pytest-repeat插件(pip install)
- --repeat-scope:重复执行作用域,与fixture作用域类似。注意,如果不加,每个用例执行指定次数后才执行下一个用例
四、pytest.ini配置
pytest.ini用于修改pytest的默认行为,一般存放于项目根目录下,文件中不能包含任何中文字符
1、增加默认命令行参数
[pytest]
addopts = -s -v --strict
2、注册mark标记
[pytest]
markers =?
? ? test1: ...(notes)
? ? test2:?...(notes)
?3、更改搜索用例行为(pytest默认执行main()所在文件目录下的所有测试用例)
执行搜索的目录
[pytest]
testpaths = test_case/
忽略部分递归搜索的目录,多个目录路径用空格隔开
[pytest]
norecursedirs = test01/ test02/
4、添加用例命名规则
?[pytest]
python_functions = test_*?new_*
python_classes = Test* New*
python_files =?test_* *_test new_*
五、fixture(重点)
1、源码详解
fixture(scope='function',params=None,autouse=False,ids=None,name=None): fixture里面有个scope参数可以控制fixture的作用范围,scope:有四个级别参数"function"(默认),"class","module","session
params:一个可选的参数列表,它将导致多个参数调用fixture功能和所有测试使用它。 autouse:如果True,则为所有测试激活fixture func可以看到它。如果为False则显示需要参考来激活fixture ids:每个字符串id的列表,每个字符串对应于params这样他们就是测试ID的一部分。如果没有提供ID它们将从params自动生成 name:fixture的名称。这默认为装饰函数的名称。如果fixture在定义它的统一模块中使用,夹具的功能名称将被请求夹具的功能arg遮蔽,解决这个问题的一种方法时将装饰函数命令"fixture_<fixturename>"然后使用"@pytest.fixture(name='<fixturename>')"。 ———————————————— 版权声明:本文为CSDN博主「王大力测试进阶之路」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_36502272/article/details/102975467
2、定义:正常定义一个函数,加上@pytest.fixture()
@pytest.fixture()
def?set():
????print('===start')
????yield 1
????print('===end')
【注】yield上面代码在测试用例前执行,yield后面代码在测试用例后执行,yield返回值在以参数传入时可被测试用例调用?
3、使用
(1)以参数传入,一般用于测试用例需要调用fixture返回值
def test_01(set):
? ? print(set)
(2)语法糖调用,一般用于fixture返回值为None
@pytest.mark.usefixtures()
def test_01(set):
? ? print(set)
(3)自动使用(在定义fixture处修改),注意,autouse作用于scope,因此需要慎重使用
@pytest.fixture(scope='function',?autouse=True)
def?set():
????print('===start')
????yield 1
????print('===end')
4、scope作用域?
scope作用域共有4个:session、module、class、function(默认)
- session,测试用例所在文件目录开始执行时调用1次,多个测试函数使用fixture时也只调用1次
- module,测试用例所在模块(py文件)开始执行时调用1次,多个测试函数使用fixture时也只调用1次
- class,测试用例所在类开始执行时调用1次,多个测试函数使用fixture时也只调用1次
- function,测试用例开始执行时调用
5、conftest.py
一般来说fixture和conftest.py配合使用效果最佳,conftest.py可以存放所有fixture函数统一管理
六、参数化
1、目的
编写测试用例时会遇到多个测试用例的结构是一致而数据不一致的情况,此时如果全部罗列出来又显得比较冗余,因此可以采用测试用例参数化来实现。
2、方法
(1)fixture前置函数参数化,使用较少
?# conftest.py
import pytest
data = [1, 2, 3]
@pytest.fixture(params=data)
def?use_data(request):
????return?request.param
# test_case.py
import requests, pytest
def?test_01(use_data):
????print(use_data)
(2)@pytest.mark.parametrize('参数名1, 参数名2', 测试数据),参数名可有1个或多个,多个时用逗号隔开,测试数据是列表的形式传入,有多个参数名时每一组数据都是以元组的方式传入。一个测试用例上面可放有多个@pytest.mark.parametrize,测试数据会进行笛卡尔积,每组数据同样并以元组的形式传入,以下两种方式等价。
@pytest.mark.parametrize('test_data_1, test_data_2', [(1, 3), (1, 4),(2, 3),(2, 4)])
def test_01(test_data_1, test_data_2):
? ? print(test_data_1)
? ? print(test_data_2)
@pytest.mark.parametrize('test_data_1', [1, 2])
@pytest.mark.parametrize('test_data_2', [3, 4])
def test_01(test_data_1, test_data_2):
? ? print(test_data_1)
? ? print(test_data_2)
(3) pytest_generate_tests():自定义参数化方案(存放于conftest.py)
def?pytest_generate_tests(metafunc):
????"""
????根据测试配置或定义测试函数的类或模块中指定的值生成测试用例,?在测试用例参数化收集前调用此钩子函数
????:param?metafunc:共有五个属性值
?????????????????????metafunc.fixturenames:参数化收集时的参数名称
?????????????????????metafunc.module:使用参数名称进行参数化的测试用例所在的模块d对象
?????????????????????metafunc.config:测试用例会话
?????????????????????metafunc.function:测试用例对象,即函数或方法对象
?????????????????????metafunc.cls:?测试用例所属的类的类对象
????:return:?none
????"""
????if?"param"?in?metafunc.fixturenames:
????????metafunc.parametrize("param,?lv",?[('print(111)',?'print(222)'),('print(33)','print(444)')],??scope="function")? # 引起参数化
总结
pytest官方文档:Full pytest documentation — pytest documentation
|