为测试函数定义一个提供多个参数的pytest fixture

2024-09-30 14:22:02 发布

您现在位置:Python中文网/ 问答频道 /正文

使用pytest,我可以这样定义fixture:

@pytest.fixture
def foo():
    return "blah"

在这样的测试中使用它:

^{pr2}$

一切都很好。但是我想做的是定义一个fixture函数,它“扩展”为一个测试函数提供多个参数。像这样:

@pytest.multifixture("foo,bar")
def foobar():
    return "blah", "whatever"

def test_stuff(foo, bar):
    assert foo == "blah" and bar == "whatever"

我想将这两个对象foo和{}一起定义(而不是单独的fixture),因为它们以某种方式相关。有时,我可能还想定义一个依赖于另一个fixture的fixture,但是让第二个fixture合并第一个fixture的结果,并将它与它自己的添加一起返回:

@pytest.fixture
def foo():
    return "blah"

@pytest.multifixture("foo,bar")
def foobar():
    f = foo()
    return f, some_info_related_to(f)

这个例子可能看起来很傻,但在某些情况下foo类似于请求对象,bar对象需要链接到同一个请求对象。(也就是说,我不能将foo和{}定义为独立的fixture,因为我需要两者都从单个请求派生出来。)

本质上,我要做的是将fixture函数的名称与测试函数参数的名称分离,这样我就可以定义一个fixture,它由测试函数签名中参数名的特定触发,而不仅仅是一个名称与fixture函数名称相同的参数。在

当然,我总是可以返回一个tuple作为fixture的结果,然后自己在test函数中解压它。但是考虑到pytest提供了各种神奇的技巧来自动匹配名称和参数,似乎它也可以神奇地处理这个问题。pytest有这种可能吗?在


Tags: 对象函数名称参数return定义foopytest
2条回答

注意:如果您的设备依赖于另一个带有参数的设备,则此解决方案不起作用

不知道pytest包中是否有默认的解决方案,但您可以定制一个:

import pytest
from _pytest.mark import MarkInfo


def pytest_generate_tests(metafunc):
    test_func = metafunc.function
    if 'use_multifixture' in [name for name, ob in vars(test_func).items() if isinstance(ob, MarkInfo)]:
        result, func = test_func.use_multifixture.args
        params_names = result.split(',')
        params_values = list(func())
        metafunc.parametrize(params_names, [params_values])


def foobar():
    return "blah", "whatever"


@pytest.mark.use_multifixture("foo,bar", foobar)
def test_stuff(foo, bar):
    assert foo == "blah" and bar == "whatever"


def test_stuff2():
    assert 'blah' == "blah"

所以我们定义了pytest_generate_tests元函数。这个函数

  1. 检查测试中是否有多像素标记
  2. 如果标记为on-它将采用变量名“foo,bar”和functionfoobar,这些变量将在生成时执行

    在@pytest.mark.multifixture(“foo,bar”,foobar)

现在可以使用pytest-cases执行此操作:

from pytest_cases import pytest_fixture_plus

@pytest_fixture_plus(unpack_into="foo,bar")
def foobar():
    return "blah", "whatever"

def test_stuff(foo, bar):
    assert foo == "blah" and bar == "whatever"

更多细节请参见documentation(顺便说一下,我是作者)

相关问题 更多 >