我试图在一次测试中多次使用参数化的夹具,目的是获得所有值的笛卡尔积。
https://stackoverflow.com/a/39444098/102441展示了如何通过简单的夹具实现此目的:
import pytest
@pytest.fixture(params=[0, 1, 2])
def first(request):
return request.param
second = first
# runs 3x3 = 9 times
def test_double_fixture(first, second):
assert False, '{} {}'.format(first, second)
但是,如果参数化来自于依赖的夹具,则这种方法会分崩离析:
import pytest
@pytest.fixture(params=[0, 1, 2])
def integer(request):
return request.param
@pytest.fixture
def squared_integer(integer):
return integer * integer
@pytest.fixture
def first(squared_integer):
return squared_integer
second = first
# runs only 3 times
def test_double_fixture(first, second):
assert False, '{} {}'.format(first, second)
如何像简单的示例一样进行3x3运行测试?
答案 0 :(得分:1)
这是pytest的正确行为。因为您在其他灯具的内部使用了integer
。要了解会发生什么,请使用--setup-show标志检查pytest。您会看到类似:
SETUP F integer[0]
SETUP F squared_integer (fixtures used: integer)
SETUP F first (fixtures used: squared_integer)
SETUP F second (fixtures used: squared_integer)
Test/test_54044536_3.py::test_double_fixture[0] (fixtures used: first, integer, second, squared_integer)F
TEARDOWN F second
TEARDOWN F first
TEARDOWN F squared_integer
TEARDOWN F integer[0]
因此,整数值仅适用于squared_integer函数。
为回答您的问题,我们可以将您的代码重构为fixture和一个函数。看起来像:
import pytest
def squared_integer(integer):
return integer * integer
@pytest.fixture(params=[0, 1, 2])
def first(request):
return squared_integer(request.param)
second = first
# runs only 3 times
def test_double_fixture(first, second):
assert False, '{} {}'.format(first, second)
您将按照以下顺序进行9个测试:
SETUP F first[0]
SETUP F second[0]
Test/test_54044536_2.py::test_double_fixture[0-0] (fixtures used: first, second)F
TEARDOWN F second[0]
TEARDOWN F first[0]
SETUP F first[0]
SETUP F second[1]
Test/test_54044536_2.py::test_double_fixture[0-1] (fixtures used: first, second)F
TEARDOWN F second[1]
TEARDOWN F first[0]
SETUP F first[0]
SETUP F second[2]
Test/test_54044536_2.py::test_double_fixture[0-2] (fixtures used: first, second)F
TEARDOWN F second[2]
TEARDOWN F first[0]
SETUP F first[1]
SETUP F second[0]
Test/test_54044536_2.py::test_double_fixture[1-0] (fixtures used: first, second)F
TEARDOWN F second[0]
TEARDOWN F first[1]
SETUP F first[1]
SETUP F second[1]
Test/test_54044536_2.py::test_double_fixture[1-1] (fixtures used: first, second)F
TEARDOWN F second[1]
TEARDOWN F first[1]
SETUP F first[1]
SETUP F second[2]
Test/test_54044536_2.py::test_double_fixture[1-2] (fixtures used: first, second)F
TEARDOWN F second[2]
TEARDOWN F first[1]
SETUP F first[2]
SETUP F second[0]
Test/test_54044536_2.py::test_double_fixture[2-0] (fixtures used: first, second)F
TEARDOWN F second[0]
TEARDOWN F first[2]
SETUP F first[2]
SETUP F second[1]
Test/test_54044536_2.py::test_double_fixture[2-1] (fixtures used: first, second)F
TEARDOWN F second[1]
TEARDOWN F first[2]
SETUP F first[2]
SETUP F second[2]
Test/test_54044536_2.py::test_double_fixture[2-2] (fixtures used: first, second)F
TEARDOWN F second[2]
TEARDOWN F first[2]
答案 1 :(得分:0)
如果您对顶级灯具的副本没有问题(在本例中,squared_integer的化身为第一和第二),您也可以复制低级灯具并将其用作灯具的另一个输入顶层一:
import pytest
@pytest.fixture(params=[0, 1, 2])
def integer(request):
return request.param
integer2 = integer
@pytest.fixture
def squared_integer(integer, integer2):
return integer * integer2
second = first = squared_integer
# runs 9 times
def test_double_fixture_lowlevel(integer, integer2):
assert False, '{} {}'.format(integer, integer2)
# also runs 9 times
def test_double_fixture_toplevel(first, second):
assert False, '{} {}'.format(first, second)