Why is Django REST Framework APITestCase unable to create the test database which is hosted on ElephantSQL?

I am currently trying to learn how to run tests in Python/Django REST Framework. I've created a database which is stored on ElephantSQL, using their free tier (tiny turtle) plan. I've connected the database successfully and have been able to create tables on there.

However, I'm trying to learn unit testing so I'm currentlt trying to use APITestCase to test the register view. My test is written as below:

import json
from django.contrib.auth.models import User
from django.urls import reverse
from rest_framework.authtoken.models import Token
from rest_framework.test import APITestCase
from rest_framework import status
from users.serializers.common import RegistrationSerializer, UserSerializer

class RegistrationTestCase(APITestCase):

  def test_registration(self):
    data = {'username': 'testuser', 'email': 'test@email.com', 'password': 'super_unique_password', 'password_confirmation': 'super_unique_password'}
    # Add a test user to database
    response = self.client.post('/api/auth/register/', data)
    # Test that 201 status is receieved
    self.assertEqual(response.status_code, status.HTTP_201_CREATED)

My databases in settings.py are set up like this:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': env('DATABASE_NAME'),
        'HOST': env('DATABASE_HOST'),
        'PORT': 5432,
            'USER': env('DATABASE_USER'),
            'PASSWORD': env('DATABASE_PASS'),
    },
    'test': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': env('DATABASE_NAME'),
        'HOST': env('DATABASE_HOST'),
        'PORT': 5432,
            'USER': env('DATABASE_USER'),
            'PASSWORD': env('DATABASE_PASS'),
    }
}

When I run python manage.py test --verbosity=2 I get the following error:

Found 1 test(s).
Skipping setup of unused database(s): test.
Creating test database for alias 'default' ('test_<database_name_here>')...
/home/ben_kelly/.local/share/virtualenvs/Siege_of_the_Citadel_Companion-eBaHHEGM/lib/python3.10/site-packages/django/db/backends/postgresql/base.py:407: RuntimeWarning: Normally Django will use a connection to the 'postgres' database to avoid running initialization queries against the production database when it's not needed (for example, when running tests). Django was unable to create a connection to the 'postgres' database and will use the first PostgreSQL database instead.
  warnings.warn(
Got an error creating the test database: permission denied to create database

I've made sure that the pqsl user is a superuser and has permission to CREATEDB.

I have also tried this without having the "test" database in settings.py but that also gave the same error.

It seems that the problem may stem from the test database prefixing the database name with "test_", however when I change the name of the database in the "test" database in settings.py it doesn't change the output after "creating test database for alias 'default'".

I tried to see which database default was accessing by using the below in the RegistrationTestCase class, however no print happens so presumably the code doesn't reach there.

 def test_database_alias(self):
      database_alias = self.client._db or 'default'
      print("Using database alias:", database_alias)

Any help would be greatly appreciated!

I believe I've solved my issue.

Changing the settings.py databases to:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': env('DATABASE_NAME'),
        'HOST': env('DATABASE_HOST'),
        'PORT': 5432,
            'USER': env('DATABASE_USER'),
            'PASSWORD': env('DATABASE_PASS'),
        'TEST': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': env('DATABASE_NAME'),
            'HOST': env('DATABASE_HOST'),
            'PORT': 5432,
            'USER': env('DATABASE_USER'),
            'PASSWORD': env('DATABASE_PASS'),
        }
    },
}

Allows the code to access the database without adding the 'test_' prefix to it.

Then running python manage.py test --keepdb prevents the 'permission denied to create database' error.

Back to Top