如何使用夹具的输出作为函数的输入作为参数化 pytest

问题描述

我的目标是从 test_addfixture 传递一个值,fixture 返回一个元组列表,需要将其作为 parametrize 传递给 test_add 函数

以下是我正在尝试但不起作用的代码

文件conftest.py

@pytest.fixture
def testme(request):
    in_value = request.param
    return [(1*in_value,1),(3*in_value,2),(4*in_value,5)]

文件test_demo.py

@pytest.mark.parametrize("testme",[(10)])
@pytest.mark.parametrize("input_a,input_b",testme)
def test_add(input_a,input_b):
    print(input_a+input_b)

预先感谢所有帮助。

解决方法

问题是您无法直接在 pytest.mark.parametrize 中访问夹具,因此这不起作用。您可以采用这种方式最接近的方法可能是在同一个测试中运行所有参数化测试:

@pytest.mark.parametrize("testme",[10],indirect=True)
def test_add(testme):
    for (input_a,input_b) in testme:
        print(input_a,input_b)

如果您想真正对测试进行参数化,则必须在运行时使用 pytest_generate_tests 进行参数化。在这种情况下,您不能使用夹具来提供所需的参数。一种可能性是使用包含该值的自定义标记,以及在运行时根据该值生成参数的函数:

def pytest_generate_tests(metafunc):
    # read the marker value,if the marker is set
    mark = metafunc.definition.get_closest_marker("in_value")
    if mark is not None and mark.args:
        in_value = mark.args[0]
        # make sure the needed arguments are there
        if metafunc.fixturenames[:2] == ["input_a","input_b"]:
            metafunc.parametrize("input_a,input_b",get_value(in_value))

def get_value(in_value):
    return [(1 * in_value,1),(3 * in_value,2),(4 * in_value,5)]

@pytest.mark.in_value(10)
def test_add(input_a,input_b):
    print(input_a,input_b)

在这种情况下,您还想在 conftest.py 中注册自定义标记以避免警告:

def pytest_configure(config):
    config.addinivalue_line("markers","in_value: provides the value for....")