在 Pytest 中参数化夹具工厂

Parameterize fixture factory in Pytest

我有一个虚拟名称工厂夹具:

@pytest.fixture
def dummy_name():
    def func(name="Dummy Name"):
        yield name
        num = 2
        while True:
            yield f"{name}_{num}"
            num += 1

    return func

我有一个利用这个的夹具:

@pytest.fixture
def dummy_document_file_name(dummy_name, extension):
    if extension:
        return dummy_name(name="test_file" + f".{extension}")
    return dummy_name(name="test_file.dummy_extension")

但是extension应该不是另一个灯具,而是这个灯具的用户提供的参数。

所以我想实现这个:

dummy_file = next(dummy_document_file_name(extension="txt")) # test_file.txt
dummy_file2 = next(dummy_document_file_name(extension="txt")) # test_file2.txt

自然会寻找另一个夹具:

  @pytest.fixture
  def dummy_document_file_name(dummy_name, extension):
E       fixture 'extension' not found
>       available fixtures: ...

有没有办法注入非夹具参数?

您可以在 fixture 装饰器中使用 params 设置默认值,request 获取传递给 fixture 的参数,pytest.mark.parameterize 装饰器在测试级别设置参数。在 pytest.mark.parameterize 中,您必须定义要参数化的夹具的名称,将参数作为可迭代对象传递,最重要的是,将间接标志设置为 True。在代码中,读起来像


@pytest.fixture(params=[None])
def dummy_document_file_name(dummy_name, request):
    if extension := request.param:
        return dummy_name(name="test_file" + f".{extension}")
    return dummy_name(name="test_file.dummy_extension")


@pytest.mark.parametrize('dummy_document_file_name', ("csv","pdf",None), indirect=True)
def test_this(dummy_document_file_name):
    print(dummy_document_file_name)
    assert True