我想对一个测试进行参数化,该列表由诸如此类的夹具动态创建:
@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-在此问题发生之前就可以解决。
我试图用夹具对测试进行参数化(这会导致错误,因为python认为我想移交函数本身):
@pytest.mark.parametrize(
"an_element_from_the_list_of_my_fixture",
my_list_returning_fixture
)
def test_the_list(an_element_from_the_list_of_my_fixture):
print(an_element_from_the_list_of_my_fixture)
像my_list_returning_fixture()
之类的普通函数一样调用灯具也会导致错误! Python不知道如何填充固定装置的“参数”(实际上只是其他固定装置),并显示有关传递的参数太少的错误消息...
因此,我需要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)
这将导致三个测试。列表中的每个元素一个。
答案 0 :(得分:2)
简短的答案是,您无法按照自己想要的方式进行操作,即无法通过夹具https://github.com/pytest-dev/pytest/issues/2155进行操作。基本上,必须预先知道产生或返回的事物数量,以便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将生成器转换为列表时,这将在收集时失败。出于相同的原因,在line_fixture
的{{1}}上添加依赖项也无济于事。
此时,您唯一的实际选择是在模块加载时或之前运行create_file
。
create_file
该列表本身不必是静态的。只是无法通过灯具创建。但是不要让那阻止你。您可以将用于定义和运行import pytest
def gen_lines():
with open('file_that_does_not_exist') as f:
yield from f
def create_file():
with open('file_that_does_not_exist', 'w') as f:
print('ABC', file=f)
print('DEF', file=f)
create_file()
@pytest.fixture(params=gen_lines())
def line_fixture(request):
return request.param
def test_line(line_fixture):
assert True
的代码放在单独的模块中,然后将其作为实用程序随时随地导入。这样可以掩盖所有混乱的细节,并使您的代码看起来像使用灯具一样干净。
答案 1 :(得分:1)
根据设计,这是不可能的:“夹具”的概念保留给测试执行,而“参数”的概念保留给测试集合。请参阅this question。