能否通过pytest parametrize向fixture传递函数而非可迭代对象?
pytest parametrize 向fixture传递函数的正确方式
核心结论
可以通过parametrize向fixture传递函数,但不能直接传函数对象(否则pytest会把它当成可迭代对象遍历,触发非预期错误),需要把函数包装成可迭代的参数列表,或者在fixture里正确接收并调用函数。
你的示例代码问题分析
你的代码存在两个关键错误:
@pytest.mark.parametrize("fixt", sample_data, indirect=True)中,sample_data是函数对象,pytest会尝试遍历它,导致不符合预期的行为;- fixture
fixt里直接把request赋值给sample_data,正确做法是用request.param获取parametrize传递的参数。
修正后的示例代码
方式1:传递函数的返回值
如果只需要函数生成的数据,直接调用函数并包装成列表即可:
import pytest @pytest.fixture def sample_data(): data = 1 return data @pytest.fixture def fixt(request): # 通过request.param获取传递的参数 data = request.param return data # 传递sample_data()的结果,包装成列表(parametrize要求第二个参数是可迭代对象) @pytest.mark.parametrize("fixt", [sample_data()], indirect=True) def test_indirect(fixt): assert fixt == 1
方式2:直接传递函数,在fixture里调用
如果需要动态调用不同函数生成数据,可以把函数本身作为参数传递,在fixture内执行:
import pytest @pytest.fixture def sample_data(): return 1 @pytest.fixture def another_data(): return 2 @pytest.fixture def fixt(request): # request.param是传递过来的函数,调用它获取数据 data_func = request.param return data_func() # 传递函数对象,包装成列表 @pytest.mark.parametrize("fixt", [sample_data, another_data], indirect=True) def test_indirect(fixt): assert fixt in (1, 2)
解决你实际项目中的错误
你遇到的TypeError: object of type 'SubRequest' has no len(),是因为fixture里错误使用request而非request.param,导致测试用例拿到的是SubRequest对象而非目标Dataframe。修正步骤如下:
- 在接收参数的fixture里,用
df = request.param获取传递的Mock Dataframe(或生成它的函数); - parametrize时,把你的MagicMock Dataframe(或生成它的函数)包装成列表。示例代码:
from unittest.mock import MagicMock import pytest @pytest.fixture def mock_df_fixture(request): # 获取传递的mock dataframe mock_df = request.param return mock_df # 定义不同的mock dataframe def get_mock_df_1(): df = MagicMock() df.__len__.return_value = 5 return df def get_mock_df_2(): df = MagicMock() df.__len__.return_value = 10 return df # 传递生成mock df的函数结果,或直接传递mock df对象 @pytest.mark.parametrize("mock_df_fixture", [get_mock_df_1(), get_mock_df_2()], indirect=True) def test_df_length(mock_df_fixture): assert len(mock_df_fixture) in (5, 10)
内容的提问来源于stack exchange,提问作者BobJones_heavyhitter
相关产品推荐
相关产品推荐

