pytest可以支持对用例自定义标记,可以把用例按自己的需要归类标记,比如按用例优先级,标记一些smoke冒烟测试用例。
1. mark标记基本实现
import pytest
@pytest.mark.smoke
def test_login1():
print('test1')
@pytest.mark.smoke
def test_login2():
print('test2')
def test_login3():
print('test3')
执行:pytest .\test_study_mark.py -m smoke
,它会只执行被smoke标记过的用例。
# 对测试类下的每个用例都会生效
@pytest.mark.dack
class TestRun:
def test_a3(self):
pass
def test_a4(self):
pass
import pytest
# 对整个测试模块下的用例全部标记
pytestmark = pytest.mark.aaa
# 对对测试类下的每个用例都会生效
@pytest.mark.dack
class TestRun:
def test_a3(self):
pass
def test_a4(self):
pass
@pytest.mark.smoke
def test_login1():
print('test1')
@pytest.mark.smoke
def test_login2():
print('test2')
def test_login3():
print('test3')
执行:pytest .\test_study_mark.py -m aaa
,它会对整个测试模块全部生效。
2. 动态添加pytestmark属性
给运行函数添加pytestmark属性,并且通过pytest.Mark动态构造mark。
import pytest
def test_login1():
print('test1')
def test_login2():
print('test2')
def test_login3():
print('test3')
# 给函数动态加pytestmark属性
test_login1.pytestmark = [
pytest.Mark(name='aaa',
args=(),
kwargs={}
)
]
给test_login1
函数动态添加了pytestmark属性,于是执行:pytest .\test_study_mark.py -m aaa
。
3. 在yaml中实现mark
在yaml文件中实现mark标记用例,需要在用例函数执行之前就添加pytestmark属性,并且添加到用例函数中。yaml文件如下所示。
# testcase/test_login2.yml
config:
name: 登录用例
variables:
username: "admin"
password: "eaton@2023"
test_login2:
name: 登录2
mark: smoke
api: api/login.yml
extract:
code1: $.code
code2: body.code
token: $.data.token
validate:
- eq: [$.code, "000000"]
- eq: [status_code, 200]
test_login3:
name: 登录3
api: api/login.yml
extract:
code1: $.code
code2: body.code
token: $.data.token
validate:
- eq: [$.code, "000000"]
- eq: [status_code, 200]
在收集用例名称和用例内容的后,收集mark关键字内容。
# utils/run.py
# ------------------ 收集 用例 mark 关键字------------
case_mark = []
if 'mark' in case[case_name][0]:
case_mark = case[case_name][0].get('mark', [])
if isinstance(case_mark, str):
case_mark = [item.strip(' ') for item in case_mark.split(',')]
elif isinstance(case_mark, int):
case_mark = [str(case_name)]
log.info(f'mark用例标记: {case_mark}')
# ------------------ 收集 用例 mark 关键字 end------------
收集mark之后,在向module中加入test函数之前,需先将pytestmark动态添加进用例函数中。于是。
# 给用例函数f,添加pytestmark属性
if case_mark:
f.pytestmark = [
pytest.Mark(name=mark_name,
args=(),
kwargs={}) for mark_name in case_mark
]
# ------为用例添加mark标记示例 end--------
# 向 module中加入test 函数
setattr(self.module, case_name, f)
执行:pytest testcase/test_login2.yml -m smoke
,如图可知,2个用例,只执行了被mark标记的用例。
3.1 在config中添加mark,全用例生效
config 中 mark 关键字添加给模块属性,对每个用例都生效。
# -------------mark 标记config 下整个yaml 中全部标记--------------#
config_mark = self.raw.get('config').get('mark', [])
if isinstance(config_mark, str):
config_mark = [item.strip(" ") for item in config_mark.split(',')]
elif isinstance(config_mark, int):
config_mark = [str(config_mark)]
if config_mark:
pytest_m = [
pytest.Mark(name=mark_name,
args=(),
kwargs={}) for mark_name in config_mark
]
log.info(f'收集到的config mark:{config_mark}')
setattr(self.module, "pytestmark", pytest_m)
# ---------mark end---------------#
case = {} # 收集用例名称和执行内容
# testcase/test_login2.yml
config:
name: 登录用例
mark: aaa
variables:
username: "admin"
password: "eaton@2023"
test_login2:
name: 登录2
mark: smoke
api: api/login.yml
extract:
code1: $.code
code2: body.code
token: $.data.token
validate:
- eq: [$.code, "000000"]
- eq: [status_code, 200]
test_login3:
name: 登录3
api: api/login.yml
extract:
code1: $.code
code2: body.code
token: $.data.token
validate:
- eq: [$.code, "000000"]
- eq: [status_code, 200]
执行用例:pytest .\testcase\test_login2.yml -m aaa