I have a set of pretest checks that I need to run, however one of the checks requires a provider to be initialized. It would appear that the way around this is to add 'foo_provider' to the fixture arguments to make sure it runs after foo_provider is run. However, I don't want to list 20 fixtures in the args of the pretest fixture.
I've tried using pytest.mark.trylast
, I've tried order markers. None of these work properly (or at all). I have tried adding various things to pytest_generate_tests
and that tends to screw up the number of tests.
I finally managed it by adding kwargs to the fixture definition and then modifying metafunc._arg2fixturedefs
through a function from pytest_generate_tests
which feels really bad.
I tried and failed with this as it ran the check too early as well:
@pytest.fixture(params=[pytest.lazy_fixture('foo_provider')], autouse=True)
def pretest(test_skipper, logger, request):
logger().info('running pretest checks')
test_skipper()
Tried and failed at reordering the fixtures like this(called from pytest_generate_tests
):
def execute_pretest_last(metafunc):
fixturedef = metafunc._arg2fixturedefs['pretest']
fixture = metafunc._arg2fixturedefs['pretest'][0]
names_order = metafunc.fixturenames
names_order.insert(len(names_order), names_order.pop(names_order.index(fixture.argname)))
funcarg_order = metafunc.funcargnames
funcarg_order.insert(len(funcarg_order),
funcarg_order.pop(funcarg_order.index(fixture.argname)))
The below code works as expected but is there a better way?
def pytest_generate_tests(metafunc):
for fixture in metafunc.fixturenames:
if fixture in PROVIDER_MAP:
parametrize_api(metafunc, fixture), indirect=True)
add_fixture_to_pretest_args(metafunc, fixture)
def add_fixture_to_pretest_args(metafunc, fixture):
pretest_fixtures = list(metafunc._arg2fixturedefs['pretest'][0].argnames)
pretest_fixtures.append(fixture)
metafunc._arg2fixturedefs['pretest'][0].argnames = tuple(pretest_fixtures)
@pytest.fixture(autouse=True)
def pretest(test_skipper, logger, **kwargs):
logger().info('running pretest checks')
test_skipper()