pytestparameterized-tests

How to use multiple pytest fixtures with same parameterized input to test methods in a class


I want to achieve something like this:

my conftest.py will contain:

@pytest.mark.parametrize('param_name', ['a', 'b', 'c'], indirect=True)
class TestDummy(object):

    def test_x(self, fixture_1):
        fixture_1_output = fixture_1
        assert False

    def test_y(self, fixture_2):
        fixture_2_output = fixture_2
        assert False

    def test_z(self, fixture_3):
        fixture_3_output = fixture_3
        assert False

Any suggestion would be highly appreciated.


Solution

  • You cannot directly patameterize the fixture name this way. Either you use parametrize for each test separately:

    def params():
       return ['a', 'b', 'c']
    
    class TestDummy:
        @pytest.parametrize(fixture_1, params, indirect=True)
        def test_x(self, fixture_1):
            fixture_1_output = fixture_1
            assert False
    
        @pytest.parametrize(fixture_2, params, indirect=True)
        def test_y(self, fixture_2):
            fixture_2_output = fixture_2
            assert False
    
        @pytest.parametrize(fixture_3, params, indirect=True)
        def test_z(self, fixture_3):
            fixture_3_output = fixture_3
            assert False
    

    (I moved the parameters into an extra function for convenience)

    Or you have to do the parametrization dynamically based on the fixture name using pytest_generate_tests:

    def pytest_generate_tests(metafunc):
        fixtures = [f for f in metafunc.fixturenames if f.startswith("fixture_")]
        if len(fixtures) == 1:
            metafunc.parametrize(fixtures[0], ['a', 'b', 'c'], indirect=True)
    
    class TestDummy:
        def test_x(self, fixture_1):
            fixture_1_output = fixture_1
            assert False
    
        def test_y(self, fixture_2):
            fixture_2_output = fixture_2
            assert False
    
        def test_z(self, fixture_3):
            fixture_3_output = fixture_3
            assert False
    
        def test_something_else(self):
            pass
    

    You need to determine which tests to parametrize - in this example all tests are parametrized which have exactly one fixture with a name starting with "fixture_", you may have to adapt ths to your needs.

    In this example, the first 3 tests will be parametrized, but not the last one (test_something_else).