Pytest:如何用fixture返回的列表参数化测试?

2024-05-28 23:38:18 发布

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

我想用一个由fixture动态创建的列表参数化测试,如下所示:

@pytest.fixture
def my_list_returning_fixture(depends_on_other_fixtures):
    return ["a dynamically created list which", depends_on_other_fixtures]

我怎么才能做到呢?或者,我如何确保a certain fixture gets called first-这可以在问题发生之前解决它呢。在


我已经试过的

  • 我试图用fixture参数化测试(这只会导致错误,因为python认为我想要移交函数本身):

    ^{pr2}$

    像调用my_list_returning_fixture()这样的普通函数也会导致错误!Python不知道如何填充fixture的“parameters”(实际上只是其他fixture),它会显示一条错误消息,说明传递的参数太少。。。在

    因此,我需要pytest注入depends_on_other_fixtures依赖项,因此不能像普通函数那样调用它。

  • 我还试图在列表固定装置和测试之间插入另一个固定装置,如下所示:

    @pytest.fixture(params=my_list_returning_fixture)
    def my_interposed_parametrized_fixture(request):
        return request.param
    
    def test_the_list(my_interposed_parametrized_fixture):
        ...
    
  • 我也尝试过间接参数化,但也没用。。。


使用静态列表

我知道很容易用给定的list参数化测试,如下所示:

the_list = [1, 2, 3]
@pytest.mark.parametrize("an_element_from_the_list", the_list)
def test_the_list(an_element_from_the_list):
    print(an_element_from_the_list)

这将导致三个测试。列表中的每个元素一个。在


Tags: the函数列表参数pytestonmydef
2条回答

这似乎是this question的副本。在

从设计上讲,这是不可能的:“fixtures”的概念是为测试执行而保留的,而“parameters”的概念是为测试集合保留的。请参阅my detailed answer here。在

简而言之,你不能按照你想要的方式来做,也就是说,通过fixture:https://github.com/pytest-dev/pytest/issues/2155。基本上,为了正确计算fixture和测试依赖关系图,pytest必须预先知道所生成或返回的东西的数量。在

看来唯一的方法是在将列表元素传递给pytests的任何装饰器之前修复它们。下面是一个与你的另一个问题相关的例子,说明这个问题不能通过一个生成器来解决:

import pytest

def gen_lines():
    with open('file_that_does_not_exist') as f:
        yield from f

@pytest.fixture(scope='session')
def create_file():
    with open('file_that_does_not_exist', 'w') as f:
        print('ABC', file=f)
        print('DEF', file=f)

@pytest.fixture(params=gen_lines())
def line_fixture(request):
    return request.param

def test_line(line_fixture):
    assert True

当pytest将生成器转换为列表时,这将在收集时失败。由于同样的原因,向create_file上的line_fixture添加依赖关系也没有帮助。在

此时,您唯一的选择是在模块加载时或之前运行create_file。在

^{pr2}$

列表本身不必是静态的。它只是不能由固定装置创建。但别让它阻止你。您可以将定义和运行create_file的代码放入一个单独的模块中,并将其作为实用程序导入任何需要的地方。这将模糊所有杂乱的细节,并使您的代码看起来像使用fixture一样干净。在

相关问题 更多 >

    热门问题