2

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()
  • Look at the answers suggested [here](https://stackoverflow.com/questions/25660064), also here's a [feature request](https://github.com/pytest-dev/pytest/issues/1216) for explicit fixture ordering which contains some useful snippets. – hoefling Apr 11 '19 at 21:34
  • I am trying to avoid listing all the provider fixtures in pretest, I can't rename all the fixtures to be alphabetical, i tried order markers and that didn't work. I guess I can try reordering the fixtures. I was hoping for a better more dynamic solution as this is what I arrived at after finding both the things you linked. Thanks – expugnosententia Apr 11 '19 at 21:43

0 Answers0