gtalarico
gtalarico

Reputation: 4699

Django using default db for unit tests instead of test db

When I run manage.py test django is using my default database instead of a test one.

Am I misunderstanding something from the docs?

According to the docs, the default behaviour is that, "separate, blank databases are created for the tests".

I set the "TEST: NAME" value just to make sure, but the docs state that's only needed if I want to configure the test database name instead of the default test_{dbname}

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql_psycopg2",
        "HOST": "0.0.0.0",
        "NAME": "mydb_db",
        "USER": "postgres",
        "PASSWORD": "postgres",
        "PORT": 5432,
        "TEST": {"NAME": "test_mydb_db"},
    }
}
from unittest import TestCase

class SimpleTest(TestCase):

    def test_get_user_authorized(self):
        client = Client()
        breakpoint()

>>> (Pdb) from django.db import connection
>>> (Pdb) connection.settings_dict['NAME']
'mydb_db'

If I read or create data in the unit test, data is from mydb_db and not test_mydb_db as I expected.

Additional Notes

Database is being setup using docker compose, but I don't think that should affect anything:

services:
  db:
    container_name: postgres
    image: postgres:9.6
    restart: always
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: mydb_db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      PGPASSWORD: postgres

Upvotes: 2

Views: 2460

Answers (1)

gtalarico
gtalarico

Reputation: 4699

Answering my own question here. Figured it out right after posting it. Looks like I missed an important point from the docs

SimpleTestCase must inherit from django.test.TestCase and not unittest.TestCase for the test database to be properly created.

Changing my code to this solved it:


from django.test import TestCase

class SimpleTest(TestCase):

def test_get_user_authorized(self):
        client = Client()
        breakpoint()
>>> (Pdb) from django.db import connection
>>> (Pdb) connection.settings_dict['NAME']
'test_mydb_db'

Docs are not explicitly stating that using unittest will not create a test db, but it does recommend using django's TestCase if db is needed:

If your tests rely on database access such as creating or querying models, be sure to create your test classes as subclasses of django.test.TestCase rather than unittest.TestCase.

Using unittest.TestCase avoids the cost of running each test in a transaction and flushing the database, but if your tests interact with the database their behavior will vary based on the order that the test runner executes them. This can lead to unit tests that pass when run in isolation but fail when run in a suite.

Upvotes: 2

Related Questions