如何从数据文件为pytest测试用例动态添加pytest.mark标记?
动态给参数化测试用例添加pytest.mark标记的可行方案
可以通过pytest的两个核心钩子函数实现:pytest_generate_tests(负责参数化测试用例并加载数据)和pytest_collection_modifyitems(负责给测试项动态添加标记),具体步骤如下:
1. 依赖准备
先安装yaml解析库:
pip install pyyaml
2. 编写钩子函数(conftest.py)
在项目根目录创建conftest.py文件,实现数据加载、参数化和标记添加逻辑:
import yaml import pytest def load_yaml_data(file_path): """加载yaml数据文件""" with open(file_path, 'r', encoding='utf-8') as f: return yaml.safe_load(f) def pytest_generate_tests(metafunc): """参数化测试用例,加载所有yaml数据""" if 'datafile_data' in metafunc.fixturenames: # 这里可以指定要加载的数据文件路径,支持多个文件 data_files = ['datafile.yaml', 'datafile2.yaml'] test_cases = [] case_ids = [] for file in data_files: data = load_yaml_data(file) for case_name, case_info in data.items(): # 将mark信息一同传入测试用例参数 test_cases.append(case_info) case_ids.append(f"{file.split('.')[0]}-{case_name}") # 给测试函数参数化 metafunc.parametrize('datafile_data', test_cases, ids=case_ids) def pytest_collection_modifyitems(items, config): """遍历测试项,动态添加mark标记""" for item in items: if hasattr(item, 'callspec'): case_data = item.callspec.params.get('datafile_data') if case_data and 'mark' in case_data: for mark_name in case_data['mark']: # 获取对应pytest标记对象并添加 target_mark = getattr(pytest.mark, mark_name, None) if target_mark: item.add_marker(target_mark)
3. 测试用例文件(testcase.py)
保持原测试用例结构不变,正常接收参数即可:
def test_somename(datafile_data): # 测试逻辑示例 print(f"当前测试数据: {datafile_data['data1']}") assert datafile_data['data1'] is not None
4. 可选:注册自定义标记(避免警告)
如果使用了自定义标记(如sanity、scale),建议在项目根目录创建pytest.ini文件注册标记,消除运行时警告:
[pytest] markers = sanity: sanity级别测试用例 scale: 压测场景用例 smoke: 冒烟测试用例
验证效果
运行pytest时可以通过标记过滤测试用例,比如只运行带smoke标记的用例:
pytest -m smoke -v
此时只会执行datafile2.yaml中定义的测试用例。
内容的提问来源于stack exchange,提问作者Vardd
相关产品推荐
相关产品推荐

