Search code examples
pythonpytest

How can I access a pytest fixture by a string?


pytest fixtures can work on other fixtures by passing them in as argument:

@pytest.fixture(scope='module')
def wrapper_fixture1(fixture1):
    fixture1.do_something()
    return fixture1

Now I have multiple different fixtures fixture1, fixture2 and fixture3 which are different, but have similarities (e.g. a function named do_something()), which I want to apply to each of them.

But instead of defining three new fixtures (like in the example), I would like to define one generic fixture/function that create three fixtures which I can pass to a test. I was thinking about something like this:

def fixture_factory():
    for index in range(3):
        fixture = pytest.get_fixture('fixture%d'%(index+1))
        fixture.do_something()
        pytest.set_fixture('wrapper_fixture%d'%(index+1), fixture, scope='module')

Can this be done in some way? Or do I have to write three wrapper fixtures for each of the original fixtures, repeating the same code over and over?


Solution

  • To get a fixture by a string, you can use request.getfuncargvalue() inside a test function or another fixture.

    You can try something along those lines:

    import pytest
    
    @pytest.fixture
    def fixture1():
        return "I'm fixture 1"
    
    @pytest.fixture(scope='module')
    def fixture2():
        return "I'm fixture 2"
    
    @pytest.fixture(params=[1, 2])
    def all_fixtures(request):
        your_fixture = request.getfuncargvalue("fixture{}".format(request.param))
        # here you can call your_fixture.do_something()
        your_fixture += " with something"
        return your_fixture
    
    def test_all(all_fixtures):
        assert 0, all_fixtures