我想在相同的参数化测试的不同实例之间共享夹具,其中夹具本身也是参数化的:
#!/usr/bin/py.test -sv
import pytest
numbers_for_fixture = [0]
def pytest_generate_tests(metafunc):
if "config_field" in metafunc.fixturenames:
metafunc.parametrize("config_field", [1], scope='session')
@pytest.fixture(scope = 'session')
def fixture_1(config_field):
numbers_for_fixture[0] += 1
return '\tfixture_1(%s)' % numbers_for_fixture[0]
@pytest.fixture(scope = 'session')
def fixture_2():
numbers_for_fixture[0] += 1
return '\tfixture_2(%s)' % numbers_for_fixture[0]
def test_a(fixture_1):
print('\ttest_a:', fixture_1)
def test_b(fixture_1):
print('\ttest_b:', fixture_1)
@pytest.mark.parametrize('i', range(3))
def test_c(fixture_1, i):
print('\ttest_c[%s]:' % i, fixture_1)
@pytest.mark.parametrize('i', range(3))
def test_d(fixture_2, i):
print('\ttest_d[%s]:' % i, fixture_2)
Run Code Online (Sandbox Code Playgroud)
我得到这个输出:
platform linux -- Python 3.4.1 -- py-1.4.26 -- pytest-2.6.4 -- /usr/bin/python
collecting …Run Code Online (Sandbox Code Playgroud) 使用 pytest,我可以像这样定义一个装置:
@pytest.fixture
def foo():
return "blah"
Run Code Online (Sandbox Code Playgroud)
并在像这样的测试中使用它:
def test_blah(foo):
assert foo == "blah"
Run Code Online (Sandbox Code Playgroud)
这一切都很好。但是我想要做的是定义一个“扩展”以向测试函数提供多个参数的单一夹具函数。像这样的东西:
@pytest.multifixture("foo,bar")
def foobar():
return "blah", "whatever"
def test_stuff(foo, bar):
assert foo == "blah" and bar == "whatever"
Run Code Online (Sandbox Code Playgroud)
我要定义的两个对象foo和bar在一起(不作为单独的固定装置),因为它们都以某种方式相关。有时我可能还想定义一个依赖于另一个夹具的夹具,但让第二个夹具合并第一个夹具的结果并将其与自己的添加一起返回:
@pytest.fixture
def foo():
return "blah"
@pytest.multifixture("foo,bar")
def foobar():
f = foo()
return f, some_info_related_to(f)
Run Code Online (Sandbox Code Playgroud)
这个例子可能看起来很傻,但在某些情况下foo就像一个请求对象,并且该bar对象需要链接到同一个请求对象。(也就是说,我不能将foo和定义bar为独立的装置,因为我需要从单个请求派生。)
本质上,我想要做的是将夹具函数的名称与测试函数参数的名称分离,以便我可以定义一个夹具,该夹具由测试函数签名中的一组特定参数名称“触发” ,而不仅仅是名称与夹具函数名称相同的单个参数。
当然,我总是可以只返回一个元组作为夹具的结果,然后自己在测试函数中解压它。但是考虑到 pytest 提供了各种神奇的技巧来自动将名称与参数匹配,看起来它也可以神奇地处理这个问题似乎并非不可想象。pytest 可以实现这样的事情吗?