Search code examples
pythonpytest

Convert a list of pytest fixtures to a parameterised fixture


Say I have a package that deals with frobs, a frob being some arbitrary object which the internal details aren't important, and which come as different types, which I'll represent using colours. I have a bunch of fixtures which return different frobs, blue ones, green ones etc. Some tests are only for specific colours (which is why they are separate fixtures), whereas others are for any frob, so I want to test with all my frob fixtures. I want to write a fixture creator which takes a list of fixtures of frobs, and generates a fixture which is parameterised over the different frobs, given that the frob fixtures may have different arguments and depend on other fixtures.

An example of what I want to do is:

@pytest.fixture
def blue_frob(tmpdir, blueness):
    return Frob(blueness, workdir=tmpdir)

@pytest.fixture
def green_frob(greenness, tmpsocket):
    return Frob(greenness, sock=tmpsocket)

all_frobs = [blue_frob, green_frob]

frobs = make_fixture_from_fixtures(all_frobs)

and then be able to use the frobs fixture in my tests.


Solution

  • What I did was use the params argument as documented at https://docs.pytest.org/en/8.0.x/reference/reference.html#pytest-fixture-api.

    So:

    @pytest.fixture
    def blue_frob(tmpdir, blueness):
        return Frob(blueness, workdir=tmpdir)
    
    @pytest.fixture
    def green_frob(greenness, tmpsocket):
        return Frob(greenness, sock=tmpsocket)
    
    all_frobs = [blue_frob, green_frob]
    
    @pytest.fixture(params=all_frobs)
    def frobs(request):
        return request.getfixturevalue(request.param)