I'm trying to use a parametrized fixture multiple times in a single test, with the intent of getting a cartesian product of all of its values.
https://stackoverflow.com/a/39444098/102441 shows how to do this for a simple fixture:
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)
However, this approach falls apart if the parametrization comes from a dependent fixture:
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)
How can I make this run 3x3 tests like the simple example does?
Module: If the Module scope is defined, the fixture will be created/invoked only once per module. Class: With Class scope, one fixture will be created per class object. Session: With the Session scope, the fixture will be created only once for entire test session.
A fixture can use multiple other fixtures. Just like a test method can take multiple fixtures as arguments, a fixture can take multiple other fixtures as arguments and use them to create the fixture value that it returns.
Fixtures with scope session will only be executed once per session. Every time you run pytest , it's considered to be one session.
m1 : is the second highest-scoped fixture ( module ). tmpdir : is a function -scoped fixture, required by f1 : it needs to be instantiated at this point because it is a dependency of f1 .
This is correct behavior of pytest. Because you use integer
deep inside other fixtures. To understand what happens check pytest with --setup-show flag. You will see something like:
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]
So integer values only for squared_integer function.
To answer you question, we can refactor your code to fixtures and one function. This will look like:
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)
And you will have 9 tests with such sequence:
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With