pytest fixture and test both dependent on another fixture

Viewed 1107

I have a pair of fixtures for testing a function with x-y inputs. One generates the x-values, the other the y-values. The test depends on both. The y-values depend on the x-values as well. Here is a summary of the setup:

import pytest

@pytest.fixture(params=['a', 'b', 'c'])
def x_data(request):
    return request.param

@pytest.fixture(params=['1', '2', '3'])
def y_data(request, x_data):
    return request.param + x_data

def test_mathfunc(x_data, y_data):
    print(f'\nTesting {x_data} vs {y_data}', end='')

When I run this with pytest -s, there are exactly 9 tests run, and the printout in test_func shows that the x_data passed in to the test is always the same as the one used to generate the y_data (which is exactly what I want, of course):

Testing a vs 1a.
Testing a vs 2a.
Testing a vs 3a.
Testing b vs 1b.
Testing b vs 2b.
Testing b vs 3b.
Testing c vs 1c.
Testing c vs 2c.
Testing c vs 3c.

I am aware of the fact that pytest caches fixture results and attempts to evaluate fixtures the minimum possible number of times. For this simple case, that would imply that the behavior is fairly reliable.

The question is, can I really rely on this behavior? Is there a situation that I am missing where the test could end up getting called with, for example, a, 3c?

1 Answers

No, it's not possible that your test case will be called with a, 3c.

All your fixtures have the "function" scope (default). It means that all of them will be called exactly once for each test function depending on them. If the fixture is dependency of two or more other dependants (fixtures or test function), it will called once anyway and the value will be reused.

Here is a paragraph in pytest docs that answers your question well: https://docs.pytest.org/en/6.2.x/fixture.html#fixtures-can-be-requested-more-than-once-per-test-return-values-are-cached

Related