3

I am setting up the test platform for a multi-tenant system.

For each written test, I want to create a test for each tenant and wrap the entire test run to change the database connexion and some thread local variable before the test without breaking the database teardown where it flushes.

During my trial-and-error process, I've resorted to climbing higher and higher in the pytest hook chain: I started with pytest_generate_tests to create a test for each tenant with an associated fixture, but the teardown failed, I've ended up at the following idea:

def pytest_runtestloop(session):
    for tenant in range(settings.TENANTS.keys()):
        with set_current_tenant(tenant):
            with environ({'DJANGO_CONFIGURATION': f'Test{tenant.capitalize()}Config'}):
                session.config.pluginmanager.getplugin("main").pytest_runtestloop(session)

    return True

Although this does not work (since django-configurations loads the settings during the earlier pytest_load_initial_conftests phase), this example should give an idea of what I am trying to achieve.

The big roadblock: The default database connection needs to point to the current tenant's database before any fixtures are loaded and after flush is ran.

I have disabled pytest-django's default session fixture mechanism and plan on using a external database for tests :

@pytest.fixture(scope='session')
def django_db_setup():
    pass

I could have a wrapper python script that calls pytest multiple times with the right config, but I would lose a lot of nice tooling.

Raphaël Gomès
  • 938
  • 1
  • 8
  • 23
  • Have you looked into parameterized fixture? – SilentGuy Oct 29 '18 at 19:40
  • https://docs.pytest.org/en/latest/proposals/parametrize_with_fixtures.html You can parametrize fixture over different types of sessions and all tests will run across all db sessions. – SilentGuy Oct 29 '18 at 19:47
  • @SilentGuy hi, I appreciate you taking the time to respond. I have indeed already looked into this, but it is unfortunately only a proposal, and nothing is implemented yet. I have not had a strong enough intensive to actually do a PR myself for now. – Raphaël Gomès Oct 29 '18 at 21:15
  • My bad. I shared the wrong link. You can parametrize fixture by using indirect parametrization. More info here: https://docs.pytest.org/en/latest/example/parametrize.html#apply-indirect-on-particular-arguments . A relevant answer: https://stackoverflow.com/a/44568273/2312300https://stackoverflow.com/a/44568273/2312300 – SilentGuy Oct 29 '18 at 22:03
  • @SilentGuy thanks for your enthusiasic help, but my issue has to do with parametrizing a much earlier stage of pytest's run, and I don't believe parameterized fixtures can help me there. – Raphaël Gomès Oct 30 '18 at 13:31
  • You can parametrize test at test collection using pytest_generate_tests(metafunc) default fixture. Source: https://pytest.readthedocs.io/en/2.7.3/example/parametrize.html – SilentGuy Oct 30 '18 at 16:39

0 Answers0