pytest混合非fixture参数时间接参数化失败问题求助
pytest间接参数化时如何显式指定fixture而非依赖参数名
问题场景
我在conftest.py中定义了一个带参数的fixture:
@pytest.fixture() def my_fixture(argument): return f'expected{argument[-1]}'
尝试直接在@pytest.mark.parametrize中显式指定my_fixture作为参数并启用间接参数化时:
@pytest.mark.parametrize('my_fixture, expected', [ ('fixture_param1', 'expected1'), ('fixture_param2', 'expected2') ], indirect=['my_fixture']) def test_indirect(my_fixture, expected): assert my_fixture == expected
会触发如下错误:
E fixture 'argument' not found
虽然通过指定argument参数名的写法可以正常运行,但这种方式易混淆,我希望能直接在parametrize中声明my_fixture来传参。
解决方案
方法1:修改fixture使用request.param接收参数
修改conftest.py中的fixture,通过pytest内置的request对象获取间接参数化的值,不再依赖argument参数:
@pytest.fixture() def my_fixture(request): # 从request.param获取parametrize中传入my_fixture的参数值 argument = request.param return f'expected{argument[-1]}'
此时原测试函数无需修改,即可正常运行:
@pytest.mark.parametrize('my_fixture, expected', [ ('fixture_param1', 'expected1'), ('fixture_param2', 'expected2') ], indirect=['my_fixture']) def test_indirect(my_fixture, expected): assert my_fixture == expected
原理说明
- 启用
indirect=['my_fixture']后,pytest会将parametrize中对应my_fixture的每一项值,通过request.param传递给fixture。 - 你之前的写法中,fixture依赖
argument,pytest会默认把argument当作一个独立fixture去查找,而非将parametrize中的值赋值给argument变量,这就是报错的核心原因。 - 使用
request.param后,fixture直接获取间接参数化的输入值,无需依赖额外的参数名,完全符合显式声明fixture的需求。
方法2:保持原fixture,通过字典映射传参(可选)
如果不想修改原fixture结构,可以在parametrize中通过字典显式传递argument的值,同时结合indirect指定fixture:
@pytest.mark.parametrize('my_fixture, expected', [ ({'argument': 'fixture_param1'}, 'expected1'), ({'argument': 'fixture_param2'}, 'expected2') ], indirect=['my_fixture']) def test_indirect(my_fixture, expected): assert my_fixture == expected
同时调整fixture接收字典参数:
@pytest.fixture() def my_fixture(request): argument = request.param['argument'] return f'expected{argument[-1]}'
这种方式也能实现显式指定my_fixture,但相比方法1多了一层字典结构,推荐优先使用方法1。
内容的提问来源于stack exchange,提问作者Raúl Núñez de Arenas Coronado
相关产品推荐
相关产品推荐

