如果我有两个参数化灯具,我怎样才能创建一个单独的测试函数,该函数首先使用一个灯具的实例调用,然后使用另一个灯具的实例调用?
我想创建一个以某种方式连接两个现有灯具的新灯具是有意义的。这适用于“普通”灯具,但我似乎无法使用参数化灯具。
以下是我尝试过的简化示例:
import pytest
@pytest.fixture(params=[1, 2, 3])
def lower(request):
return "i" * request.param
@pytest.fixture(params=[1, 2])
def upper(request):
return "I" * request.param
@pytest.fixture(params=['lower', 'upper'])
def all(request):
return request.getfuncargvalue(request.param)
def test_all(all):
assert 0, all
当我运行时,我收到此错误:
request = <SubRequest 'lower' for <Function 'test_all[lower]'>>
@pytest.fixture(params=[1, 2, 3])
def lower(request):
> return "i" * request.param
E AttributeError: 'SubRequest' object has no attribute 'param'
...和upper()
的错误相同。
我做错了什么?
我该如何解决这个问题?
更新
有一个PyTest插件可用于解决此问题:https://github.com/TvoroG/pytest-lazy-fixture。
pip
- 安装此插件后,对上述代码的唯一必要更改如下:
@pytest.fixture(params=[pytest.lazy_fixture('lower'),
pytest.lazy_fixture('upper')])
def all(request):
return request.param
但请注意,与当前的PyTest版本3.6.3不兼容,请参阅https://github.com/TvoroG/pytest-lazy-fixture/pull/27。
相关的PyTest问题:
答案 0 :(得分:2)
它并不美丽,但今天你可能知道更好的方式。
请求对象内部&#39;所有&#39;夹具只知道自己的params:&#39; lower&#39;,&#39; upper&#39;。一种方式using fixtures from a fixture function。
import pytest
@pytest.fixture(params=[1, 2, 3])
def lower(request):
return "i" * request.param
@pytest.fixture(params=[1, 2])
def upper(request):
return "I" * request.param
@pytest.fixture(params=['lower', 'upper'])
def all(request, lower, upper):
if request.param == 'lower':
return lower
else:
return upper
def test_all(all):
assert 0, all
答案 1 :(得分:0)
pytest-cases
中现在有一个名为fixture_union
的解决方案。这是创建示例中要求的夹具联合的方法:
from pytest_cases import fixture_union, pytest_fixture_plus
@pytest_fixture_plus(params=[1, 2, 3])
def lower(request):
return "i" * request.param
@pytest_fixture_plus(params=[1, 2])
def upper(request):
return "I" * request.param
fixture_union('all', ['lower', 'upper'])
def test_all(all):
print(all)
它按预期工作:
<...>::test_all[lower-1]
<...>::test_all[lower-2]
<...>::test_all[lower-3]
<...>::test_all[upper-1]
<...>::test_all[upper-2]
请注意,在上例中,我使用了pytest_fixture_plus
,因为如果您使用pytest.fixture
,您将不得不自己处理未实际使用灯具的情况。例如,对于upper
固定装置,执行以下操作:
import pytest
from pytest_cases import NOT_USED
@pytest.fixture(params=[1, 2])
def upper(request):
# this fixture does not use pytest_fixture_plus
# so we have to explicitly discard the 'NOT_USED' cases
if request.param is not NOT_USED:
return "I" * request.param
有关详细信息,请参见documentation。 (顺便说一下,我是作者;))