Running tests against existing database using pytest-django

Question:

Does anybody know how to run Django Tests using pytest-django against an existing (e.g. production) database?

I know that in general, this is not what unit tests are supposed to do, but in my case, I’m running the tests on Heroku. By default, Django creates a new test database, however, this is not possible on Heroku.

I found a solution that would work without pytest-django (python manage.py test): https://gist.github.com/gregsadetsky/5018173
but as far as I understood, pytest-django doesn’t make use of the test runner defined in the Django settings.

If anybody has another approach on how to run Django tests using pytest-django on Heroku (e.g. by automating a way to create the test database) I would be happy with that solution as well.

Asked By: lmr2391

||

Answers:

Following the documentation on how to link to an existing database:

Using an existing, external database for tests

This example shows how you can connect to an existing database and use it for your tests.

This example is trivial, you just need to disable all of pytest-django and Django’s test database creation and point to the existing database. This is achieved by simply implementing a no-op django_db_setup fixture.

Put this into conftest.py:

import pytest


@pytest.fixture(scope='session')
def django_db_setup():
    settings.DATABASES['default'] = {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'db.example.com',
        'NAME': 'external_db',
    }
Answered By: John Moutafis

For those for whom the solution above does not work. You can specify a different settings.py file in pytest.ini. Like:

[pytest]
DJANGO_SETTINGS_MODULE = tests.settings

Then in the new settings.py file, import all the settings from the regular settings.py and override DATABASES:

from core.settings import *  # your usual settings

# Dadabase configuration for tests
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
        'ATOMIC_REQUESTS': True,
    }
}

In tests.settings.py you can also override other variables for testing and it will all be in one place.

I know that this won’t allow you to take full advantage of the pytest fixture (such as setting the scope, and pointing to specific tests). But this is the best solution I found for specifying a custom database for tests.

Answered By: Protages