目录
2.2 使用装饰器@pytest.mark.usefixtures()修饰需要运行的用例
一、命名原则
- 测试用例文件名必须以
test_*.py
和*_test.py
开头或结尾 - 测试类名必须以Test开头,并且不能有__init__方法,测试方法必须以
test_
开头的函数 - 如果没有类名,那么以函数为单位的函数名必须以
test_
开头 - 文件夹(包名)名可以随意命名
pytest的main方法运行方式
if __name__ == '__main__': pytest.main(['参数','文件名.py'])
二、命令参数
常用的命令参数:
pytest ‐x # 如果出现一条测试用例失败,则退出测试
pytest ‐‐maxfail=num # 用例失败总数等于num 时停止运行
-q, --quiet # 极简结果显示
-V # 可以输出用例更加详细的执行信息,比如用例所在的文件及用例名称等
-s # 输出用例中调试信息,如print的打印信息
-v --verbose # 详细结果
--junit-xml=path # 输出xml格式文件,与jenkins做集成时使用
--result-log=path # 将最后的结果保存到本地文件中
ps:橙色为出现频率较高的命令
三、指定测试
1. 在模块中运行测试
pytest test_mod.py
2. 在目录中运行测试
pytest testing/
3. 按关键字表达式运行测试
pytest -k "01" test_02.py
会执行 test_02.py 下 01 的方法,用于匹配"文件名、类名、方法名"符合表达式的的测试用例
4. 通过节点 id 来进行测试
参数化的类名、函数名和参数,用::
分隔。
规则 pytest 目录 / py文件 :: 类名 : 方法名
例子 pytest testcase/test_02.py::TestDemo02:test_01
5. 通过标记来执行 (只能运行有相应标识的测试用例)
- pytest -m "tag01 or tag02" # 运行tag01和tag02的标记用例
这种方式会运行所有通过装饰器 @pytest.mark.mark
进行装饰的测试用例
@pytest.mark.tag01
def test_01(self):
assert self.func(3) == 4
@pytest.mark.tag02
def test_02(self):
assert self.func(3) == 4
- pytest -m tag # 执行test_01.py内所有@pytest.mark.tag的标记用例
四、pytest fixture
- 模块形式----使用setup_module/teardown_module
- 函数形式----使用setup_function/teardown_function
- 类形式----使用setup_class/teardown_class
- 方法形式---使用setup_method/teardown_method
1. fixture scope的范围参数
@pytest.fixture(scope='module')来定义框架,scope的参数有以下几种
- function 每一个用例都执行
- class 每个类执行
- module 每个模块执行(函数形式的用例)
- session 每个session只运行一次,在自动化测试时,登录步骤可以使用该session
2. 调用fixture的三种方法
2.1 函数或类里面方法直接传fixture的函数参数名称
from __future__ import print_function
import pytest
@pytest.fixture(scope='module') #范围是module
def resource_a_setup(request): #前置器
print('\n resources_a_setup()')
def resource_a_teardown(): #后置器
print('\n resources_a_teardown()')
request.addfinalizer(resource_a_teardown)
def test_1(resource_a_setup):
print('test_1()')
def test_2():
print('\ntest_2()')
def test_3(resource_a_setup):
print('\ntest_3()')
2.2 使用装饰器@pytest.mark.usefixtures()修饰需要运行的用例
@pytest.fixture()
def test1(): #套件名test1
print('\n开始执行function')
@pytest.mark.usefixtures('test1') #方法使用套件test1
def test_a():
print('---用例a执行---')
@pytest.mark.usefixtures('test1') #类使用套件test1
class TestCase:
def test_b(self):
print('---用例b执行---')
def test_c(self):
print('---用例c执行---')
if __name__ == '__main__':
pytest.main(['-s', 'test_fixture1.py'])
2.3 叠加usefixtures
如果一个方法或者一个class用例想要同时调用多个fixture,可以使用@pytest.mark.usefixture()进行叠加。注意叠加顺序,先执行的放底层,后执行的放上层
@pytest.fixture()
def test1(): #套件test1
print('\n开始执行function1')
@pytest.fixture()
def test2(): #套件test2
print('\n开始执行function2')
@pytest.mark.usefixtures('test1')
@pytest.mark.usefixtures('test2')
def test_a(): #方法使用套件test1和test2
print('---用例a执行---')
#或
@pytest.mark.usefixtures('test2')
@pytest.mark.usefixtures('test1')
class Testcase: #类使用套件test1和test2
def test_c(self):
print('---用例c执行---')
if __name__ == '__main__':
pytest.main(['-s', 'test_fixture1.py'])
3. fixture和usefixture区别
如果fixture有返回值,那么usefixture就无法获取到返回值
五、conftest全局处理器
conftest.py通常可以用来做2个事情:
- 存放你的
fixture
函数 - 在里面写自己的本地插件
conftest.py作用全局,不可跨模块调用,作用范围只能在该层级以及以下目录生效
另外,可以根据conftest.py
的文件存放位置,来决定它的适用范围,实际应用需要结合fixture来使用。
# /test_module_01/conftest.py
# 作用于test_module_01下的py文件
import pytest
@pytest.fixture
def demo_fixture():
print("这是fixture函数的输出")
六、参数化
@pytest.mark.parametrize("参数名",列表数据)
参数名:用来接收每一项数据,并作为测试用例的参数。
列表数据:测试数据,支持列表、元组、字典列表、字典元组,有多少值用例就执行多少次
# 和unittest的ddt里面@unpack解包相同
方式一:直接写入
class Testapi
@pytest.mark.parametrize('name,arg',[['赵四','24'],['张三','25']])
def test_01(self,name,arg):
print(name,arg)
if __name__ == '__main__':
pytest.main
方式二:参数为列表中嵌套元组或字典
class Testapi
date_dicts = [
{'user':01,'pwd':123},
{'user':02,'pwd':123},
{'user':03,'pwd':123}
]
@pytest.mark.parametrize("data",date_dicts)
def test_01(data):
print(data)