pythondjangopytestpostgispytest-django

Django does not automatically create test database


I have a Django project, version - 3.2.25. The problem I'm facing is that I'm unable to create a test database, when I'm executing my tests using VScode test runner. If matters here are the pytest versions:

 name         : pytest                                      
 version      : 8.2.2                                       
 description  : pytest: simple powerful testing with Python 

required by
 - pytest-django requires >=5.4.0
 - pytest-dotenv requires >=5.0.0

Basically, I have a test case, which uses my local database, I want to start using a virtual database, which is dynamically created when executing a test, instead of a local one. To do that, I've tried to set a Test property inside my settings.py database configuration:

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"
        },
    },
}

So inside my test case:

class BillAPITests(APITestCase):
    def test_create_bill(self):
        from django.db import connection
        print(connection.settings_dict["NAME"]
        response = self.client.post(self.base_url, self.base_payload, format="json")
        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

the print gives me:

localDatabase

instead of "test_local".

As second attempt, I have tried settings up a pytest.fixture inside my conftest.py:

@pytest.fixture(scope="session")
def django_db_setup():
    load_dotenv()
    
    settings.DATABASES["default"] = {
        "NAME": "test_local",
        "ENGINE": "django.contrib.gis.db.backends.postgis",
        "USER": "test",
        "PASSWORD": "test",
        "HOST": "127.0.0.1",
        "PORT": "5432",
    }

Still the same output...

I have also tried closing all connections in the `django_db_setup` before swapping my default databases using:
```py
from django import db
db.connections.close_all()

No result...

The only thing that gave me different behaviour is settings the database name directly in the django_db_setup, like so:

settings.DATABASES["default"]["NAME"] = "test_local"

However, that way django does not automatically create me "test_local" database and it fails connecting to it.

Any help appreciated, thanks


Solution

  • The problem in my case was, that I've overridden the default creation of test database by Django, when running the tests. This happened by obsolete pytest fixture that i had in my conftest.py. As @willeM_ Van Onsem confirmed, Django by default creates a test database by appending test_ to the name of your default to use database.

    In order to check which database are you using, just add a print statement into a test case:

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

    This will NOT print your default database name, but will print the database name of the currently used database.

    In my case, my database configuration ended up like:

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

    and when running the tests, the currently used database name is - "test_localDatabase".

    As you can see, I have removed the "TEST" key property from DATABASES , because it overrides the default Django logic of generating a new name for the test database.