我想使用由夹具动态创建的列表来参数化测试,如下所示:
@pytest.fixture
def my_list_returning_fixture(depends_on_other_fixtures):
return ["a dynamically created list which", depends_on_other_fixtures]
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?或者,我如何确保首先调用某个夹具- 这将在它发生之前解决这个问题。
我试图用夹具参数化测试(这只会导致错误,因为 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)
Run Code Online (Sandbox Code Playgroud)
像普通函数一样调用夹具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):
...
Run Code Online (Sandbox Code Playgroud)我也尝试使用间接参数化,但它也不起作用......
我知道可以很容易地使用给定的参数对测试进行参数化,如下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)
Run Code Online (Sandbox Code Playgroud)
这将导致三个测试。列表中的每个元素一个。
简短的回答是你不能按照你想要的方式来做,即通过装置: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
Run Code Online (Sandbox Code Playgroud)
当 pytest 将您的生成器转换为列表时,这将在收集时失败。出于同样的原因,添加对line_fixture
on的依赖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
Run Code Online (Sandbox Code Playgroud)
该列表本身不必是静态的。它不能由夹具创建。但不要让它阻止你。您可以将用于定义和运行的代码create_file
放在一个单独的模块中,然后将其作为实用程序导入到任何需要的地方。这将掩盖所有杂乱的细节,并使您的代码看起来像使用设备一样干净。
归档时间: |
|
查看次数: |
4767 次 |
最近记录: |