On , I learnt ...

About indirect parametrization with Pytest

Pytest’s pytest.mark.parametrize function supports an indirect argument that allows a parametrized test to have its parameter passed to a fixture function, rather than directly into the test function.

This is useful for deferring expensive set-up to be executed at test runtime, rather than at collection time.

To illustrate, here’s an example of direct parametrization where the value of x is passed directly into the test function:

import pytest

@pytest.mark.parametrize("x", (1,2,3))
def test_direct(x):
    assert x > 0

And here’s an example of indirect parametrization where the first argument to pytest.mark.parametrize is the name of a fixture:

import pytest

@pytest.fixture
def x(request):
    """
    Transform the value of "x" before it is passed to the test.
    """
    return request.param * 100

@pytest.mark.parametrize("x", (1,2,3), indirect=True)
def test_indirect(x):
    assert x > 100

In my opinion, it reads awkwardly as the fixture and the parameter need to share the same name. Above, the fixture needs to be named x but it would be better named multiply or something like that.

It’s also possible to transform only some of the arguments injected by pytest.mark.parametrize.