Skip to content
Advertisement

Pytest: Nested use of request fixture

I’d like to get some help on how to run pytests with multiple layers of parameterized pytest fixtures.

I have a global request-based fixture for selecting a base implementation of the system I’d like to test:

@fixture()
def a_provider():
    yield 'a'


@fixture()
def b_provider():
    yield 'b'


@fixture(params=["a_provider", "b_provider"])
def letter_provider(request):
    yield request.getfixturevalue(request.param)

I’d like to now run some additionally-parametrized tests against different test cases on the backend.

@fixture()
def one(letter_provider):
    yield letter_provider * 1


@fixture()
def two(letter_provider):
    yield letter_provider * 2


@fixture(params=["one", "two"])
def letter_cases(request):
    yield request.getfixturevalue(request.param)

Using these two layers of fixtures, I’d like to be able to run both tests parameterised by the base-implementation.

def test_foo(letter_provider):
    """
    Should run once for "a" and once for "b"
    """
    assert letter_provider in {"a", "b"}

And tests that use all the additional cases

def test_bar(letter_cases):
    """
    test should be executed 4 times for : a, aa, b, bb
    """
    assert letter_cases in {
        "a", "aa",
        "b", "bb",
    }

At the moment, my test setup fails with:

test setup failed
'letter_provider'

The above exception was the direct cause of the following exception:
letter_provider

During handling of the above exception, another exception occurred:
The requested fixture has no parameter defined for test:
    tests/test_example.py::test_bar[one]

Requested fixture 'letter_provider' defined in:
tests/test_example.py:15

How could I set up my test suite to run these levels of parameterization?

Advertisement

Answer

Ensure the fixture cache is filled with one and two fixture values when calling getfixturevalue() by adding both fixtures as letter_cases dependencies:

@fixture(params=["one", "two"])
def letter_cases(request, one, two):
    yield request.getfixturevalue(request.param)
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement