You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过与测试同名的配置文件实现pytest测试用例参数化?

问题与解决方案

问题描述

我想创建一个用输入参数驱动的测试用例,参数存储在项目下的cfg配置文件中,核心需求是找到与当前运行测试同名的cfg文件。我可以通过fixture(借助request.node.name获取文件名)获取cfg文件内容,但@pytest.mark.parametrize装饰器无法访问该内容。

pytest参数化测试的基础写法如下:

@pytest.mark.parametrize("input,expected", [(param1, param2)])
def test_example(input, expected):
    # 如何在此处访问cfg数据?

以下是conftest.py中返回cfg内容的fixture:

@pytest.fixture(scope="function")
def cfg_data(request):
    cfg_name = f'{request.node.name}.cfg'
    cfg_template_dir = eval(settings.cfg_tests_folder)
    cfg_template_file = Path(cfg_template_dir).joinpath(cfg_name)
    with open(cfg_template_file, 'r') as cfg_data:
        cfg_data_dict = yaml.safe_load(cfg_data)
        return cfg_data_dict

我希望使用cfg内容对以下测试用例进行参数化:

def test1(cfg_data, tests_client, settings_data):
    tests_client.load_data(settings_data.csv_file_name)
    # 使用cfg_data作为参数执行测试

另外想请教:是否可以让fixture脱离测试的作用域(或在测试类中使用,以便该类下的测试可以调用它)?

已实现的解决方案

按照建议,我完成了如下实现:

# 加载仅参数化测试所需的所有参数
def load_test_params(test_name) -> object:
    test_name = test_name.split('[')[0]
    cfg_name = f'{test_name}.cfg'
    cfg_template_dir = eval(settings.cfg_tests_folder)
    cfg_template_file = Path(cfg_template_dir).joinpath(cfg_name)
    if cfg_template_file.exists():
        with open(cfg_template_file, 'r') as cfg_data:
            cfg_data_dict = yaml.safe_load(cfg_data)
            return cfg_data_dict

def pytest_generate_tests(metafunc):
    """
    生成参数化测试所需的参数。
    :param metafunc: pytest内置函数
    """
    fct_name = metafunc.function.__name__
    if fct_name.startswith('test_param'):
        parameterized_data = load_test_params(fct_name)
        if parameterized_data.get(fct_name):
            params = parameterized_data[fct_name]
            metafunc.parametrize(params["params"], params["values"])

内容的提问来源于stack exchange,提问作者ollie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:42:40