使用夹具进行参数化测试时不存在间接夹具

Indirect fixture doesn't exist when parametrising tests with fixtures

我正在使用 pytest,我正在尝试将夹具作为参数化测试中的值传递。我阅读了参数化测试和 indirect = True 参数的文档,但是当我尝试 运行 时,我不断收到错误消息。我需要不同对象的固定装置进行不同的测试,我有以下代码:

#in user.py

class User(object):
    def __init__(self, first_name: str, last_name: str):
        self.first_name = first_name
        self.last_name = last_name

    def create_full_name(self):
        return f'{self.first_name} {self.last_name}'

#in conftest.py

@pytest.fixture(scope='function')
def normal_user():
    '''Returns a normal user'''
    normal_user = user.User(first_name = 'katherine', last_name = 'rose')
    yield normal_user

@pytest.fixture(scope='function')
def missing_details():
    '''Returns a user without a last name'''
    missing_details = user.User(first_name = ' ', last_name = 'rose')
    yield missing_details

#in test_user.py

@pytest.mark.parametrize('user, expected', [('normal_user', 'katherine rose'), ('missing_details', TypeError)], indirect= ['normal_user', 'missing_details'])
def test_parametrize_user_full_name(user, expected):
    assert user.create_full_name(user) == expected

我不断收到的错误信息是: In test_parametrize_user_full_name: indirect fixture 'normal_user' doesn't exist

是否有必要在 conftest.py 中指定哪些灯具应该是间接的,或者我是否为参数化测试编写了错误的代码?

这不是间接参数化的工作方式。您必须使用间接参数引用一个灯具,灯具将根据参数值列表中的值 return 实际值。您可以在 documentation.

中找到示例

在你的情况下,你需要这样的东西:

@pytest.fixture
def user(request):
    if request.param == 'normal_user':
        # Returns a normal user
        yield User(first_name='katherine', last_name='rose')
    if request.param == 'missing_details':
        # Returns a user without a last name
        yield User(first_name=' ', last_name='rose')


@pytest.mark.parametrize('user, expected', [('normal_user', 'katherine rose'),
                                            ('missing_details', TypeError)],
                         indirect=['user'])
def test_parametrize_user_full_name(user, expected):
    ...

顺便说一句:将结果与异常进行比较不会像您那样工作,但我想这只是一个愚蠢的例子,预计不会工作。