2025, Oct 18 19:00

Django tests using the real database? How to restore isolated test DB with pytest-django in VS Code

Learn why Django pytest tests hit the primary database and how to fix it. Remove conftest.py overrides to restore an isolated test DB in the VS Code runner.

Django test suites should run against an isolated database, not your local working one. Yet it’s surprisingly easy to end up hitting the primary database when wiring pytest, pytest-django, and a custom test runner from an IDE. Below is a concise walkthrough of what goes wrong, how to verify which database your tests are actually using, and the minimal configuration that restores Django’s default, safe behavior.

The symptom

Tests are executed through a VS Code test runner in a Django 3.2.25 project with pytest 8.2.2. The expectation is that a throwaway database will be created dynamically for test execution. Instead, the test code shows that the connection points at the regular database name.

Problem demonstration

The database configuration explicitly declares a TEST section, and the test prints the active database name:

DATABASES = {
    'default': {
        "NAME": "localDatabase",
        "ENGINE": "django.contrib.gis.db.backends.postgis",
        "USER": "test",
        "PASSWORD": "test",
        "HOST": "127.0.0.1",
        "PORT": "5432",
        "TEST": {
            "NAME": "test_local"
        },
    },
}
from rest_framework.test import APITestCase
from rest_framework import status
from django.db import connection

class InvoiceApiSpec(APITestCase):
    def test_can_create_invoice(self):
        print(connection.settings_dict["NAME"])  # Expected a test DB name
        resp = self.client.post(self.endpoint, self.sample_payload, format="json")
        self.assertEqual(resp.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

The print outputs localDatabase instead of the intended test database name.

What’s really happening

Django by default creates a dedicated test database by prefixing the configured database name with test_. That is the built-in behavior when running tests. However, an obsolete pytest fixture in conftest.py had overridden Django’s default test database creation flow. As a result, the test runner did not provision the temporary database and continued to use the original database settings as-is.

To validate what database is currently in use during a test, retrieve the connection name:

from django.db import connection
connection.settings_dict["NAME"]

This prints the actual database your test connection is using at runtime, not merely what is configured in settings.py.

The fix

Restore Django’s default behavior by removing the override that interferes with test database creation and avoid forcing a test NAME via DATABASES["default"]["TEST"]. With the override gone and the TEST key removed, Django will automatically create a database named test_<original_name> for the duration of the test run.

A working configuration looks like this:

DATABASES = {
    'default': {
        "NAME": "localDatabase",
        "ENGINE": "django.contrib.gis.db.backends.postgis",
        "USER": "test",
        "PASSWORD": "test",
        "HOST": "127.0.0.1",
        "PORT": "5432",
    },
}

With that in place, running tests uses a transient database named test_localDatabase. There is no need to set TEST["NAME"] or manually rewrite settings in a fixture. Attempts like settings.DATABASES["default"]["NAME"] = "test_local" bypass Django’s automatic provisioning and lead to connection failures because the database is not created for you.

Why this matters

Test isolation prevents accidental data corruption and makes results reproducible. Allowing Django to create and manage a temporary test database ensures clean state across runs and avoids subtle cross-test interference. Verifying the active database name inside a test is a quick sanity check that you’re not hitting the local working database.

Takeaways

Let Django handle test database creation by default. Remove custom overrides in conftest.py that change how databases are provisioned, and avoid hardcoding TEST["NAME"] when you don’t need a custom name. If you ever doubt which database is in use, print connection.settings_dict["NAME"] inside a test; it reflects the currently active connection, which during test runs should be the auto-created test_<name> database.

The article is based on a question from StackOverflow by Geo and an answer by Geo.