pytest parametrize using values from a fixture

Viewed 56

I have a fixture (lets call it class_fixture) that dynamically returns a class I wish to run tests on.

I have another fixture (lets call it methods_fixture) that uses class_fixture and returns the names of all methods (that fit a specific criteria) of that class.

I also have a test that uses both fixtures and performs certain checks all methods:

def test_methods(class_fixture, methods_fixture):
    for method in methods_fixture:
        # DO TESTS ON class_fixture.method, for our example, lets test method name starts with DUMMY
        assert getattr(class_fixture, method).__name__.startswith("DUMMY")

I would like to convert that test to be parameterized and be similar to the following:

def test(class_fixture, methods_fixture_as_parameter):
    # This test function should generate multiple tests, one for each method returned by `methods_fixture`
    # DO TESTS ON class_fixture.method, for our example, lets test method name starts with DUMMY
    assert getattr(class_fixture, methods_fixture_as_parameter).__name__.startswith("DUMMY")

I tried going over pytest's parametrize documentation and couldn't find anything that fits. Since methods_fixture depends on a different fixture, I can't seem to implement what I want (because I assume I don't have the list of methods at test-creation time).

I couldn't get it to work with indirect, although it might be possible.

I also tried adding a pytest_generate_tests hook, but couldn't reach the values of methods_fixture or class_fixture to actually set the parameter values.

1 Answers

You can replace the fixtures with a function that iterate over the classes and their methods from parametrize decorator

def class_fixture_imp():
    return []


@pytest.fixture
def class_fixture():
    return class_fixture_imp()


def methods_data():
    c = class_fixture_imp():
    for f in methods_fixture(c):
        yield c, f

@pytest.mark.parametrize('data', methods_data())
def test_something(data):
    cl, method = data
    assert getattr(cl, method).__name__.startswith("DUMMY")
Related