如何修改PyTest测试输出中Fixture参数显示为模板name字段?
问题:自定义PyTest Fixture参数显示名称,替换默认的template+数字标识
我使用PyTest编写了多个Python测试函数,通过Fixture传入解析自JSON文件的模板字典进行测试。测试失败时,输出中显示的是PyTest自动分配的[template78]这类标识,为了准确解读测试结果,我需要将其替换为模板的template['name']字段值。
当前测试失败输出
FAILED tests/test_device_group.py::test_device_group_staging_type[template78] - assert False FAILED tests/test_device_group.py::test_device_group_staging_type[template109] - assert False ...
期望输出
FAILED tests/test_device_group.py::test_device_group_staging_type[my_template] - assert False FAILED tests/test_device_group.py::test_device_group_staging_type[testing_template] - assert False ...
我的测试文件代码
import json import pytest import pathlib templates = './templates/device_groups' list_of_templates = [] d = pathlib.Path(templates) for entry in d.iterdir(): if entry.is_file(): list_of_templates.append(entry) @pytest.fixture(params=list_of_templates) def template(request): with open(request.param) as file: template = json.loads(file.read()) return template def test_device_group_description(template: dict): ''' Description must be present ''' if 'description' in template: if template['description'] != '': assert True else: assert False else: assert False, 'Description is empty.' def test_device_group_staging_type(template: dict): ''' Staging must be configured ''' if template['enable-staging-url']: if template['staging-type'] == 'staging': assert True else: assert False
解决方案
通过给Fixture的params搭配ids参数,自定义每个参数的显示名称即可实现需求,具体步骤如下:
- 新增获取模板名称的辅助函数:读取每个JSON文件,提取
name字段,若不存在则用文件名作为 fallback - 生成自定义ID列表:遍历所有模板文件,用辅助函数生成对应的名称列表
- 修改Fixture定义:在
@pytest.fixture装饰器中添加ids参数,传入自定义的名称列表
修改后的完整代码
import json import pytest import pathlib templates = './templates/device_groups' d = pathlib.Path(templates) def get_template_name(file_path): """读取模板文件,返回name字段,不存在则返回文件名""" with open(file_path) as f: template = json.load(f) return template.get('name', file_path.stem) # 生成模板文件列表和对应的自定义ID列表 list_of_templates = [entry for entry in d.iterdir() if entry.is_file()] template_ids = [get_template_name(entry) for entry in list_of_templates] @pytest.fixture(params=list_of_templates, ids=template_ids) def template(request): with open(request.param) as file: template = json.loads(file.read()) return template def test_device_group_description(template: dict): ''' Description must be present ''' if 'description' in template: if template['description'] != '': assert True else: assert False else: assert False, 'Description is empty.' def test_device_group_staging_type(template: dict): ''' Staging must be configured ''' if template['enable-staging-url']: if template['staging-type'] == 'staging': assert True else: assert False
原理说明
PyTest的Fixture装饰器支持ids参数,该参数接受一个与params长度一致的列表,列表中的每个元素会作为对应位置参数的显示标识。通过提前读取每个模板的name字段生成自定义ID列表,测试输出时就会用模板名称替代默认的template+数字格式,方便快速定位失败的模板。
内容的提问来源于stack exchange,提问作者Lawrence Bird
相关产品推荐
相关产品推荐

