首页 文章

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

提问于
浏览
3

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

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

并在这样的测试中使用它:

def test_blah(foo):
    assert foo == "blah"

这一切都很好 . 但我想要做的是定义一个夹具函数"expands"为测试函数提供多个参数 . 像这样的东西:

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

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

我想一起定义两个对象 foobar (而不是单独的灯具),因为它们以某种方式相关 . 我有时也可能想要定义一个依赖于另一个夹具的夹具,但让第二个夹具包含第一个夹具的结果并将其与其自身的添加一起返回:

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

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

这个例子可能看起来很愚蠢,但在某些情况下 foo 类似于Request对象, bar 对象需要链接到同一个请求对象 . (也就是说,我无法将 foobar 定义为独立装置,因为我需要从单个请求中派生两者 . )

本质上,我想要做的是将fixture函数的名称与test-function参数的名称分离,这样我就可以通过测试函数签名中的一组特定参数名来定义一个"triggered"的fixture,而不是只是一个参数,其名称与fixture函数的名称相同 .

当然,我总是可以返回一个元组作为夹具的结果,然后在测试功能中自己解压缩 . 但是考虑到pytest为自动匹配名称和参数提供了各种神奇的技巧,看起来它也可以神奇地处理它并不是不可想象的 . 用pytest这样的事情可能吗?

1 回答

  • 0

    note: 如果您的灯具依赖于带参数的其他灯具,此解决方案无效

    不知道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元函数 . 这个功能

    • 检查测试中是否有多标记标记

    • 如果标记打开 - 它将采用将在生成时执行的变量名称"foo,bar"和fucntion foobar

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

相关问题