Make Django Tests Always Rebuild the Database if It Exists

2020-01-13 Test Machine

If you use Django’s test runner, you’ll probably have encountered this message:

$ python manage.py test
Creating test database for alias 'default'...
Got an error creating the test database: database "myproject_test" already exists

Type 'yes' if you would like to try deleting the test database 'myproject_test', or 'no' to cancel:

The main reason this happens is that the last test run crashed and it left the database around. It can be annoying when you start the test run, go for a cup of tea, and come back to this prompt still waiting, rather than a complete test run.

Here’s how to make Django always rebuild the database in this case.

We’ll do it by extending test with our own custom management command.

Create a new test management command inside one of your Django apps, for example testapp/management/commands/test.py. Then add this content:

from django.core.management.commands.test import Command as BaseCommand


class Command(BaseCommand):
    def handle(self, *test_labels, **options):
        # Wrap Django's built-in test command to always delete the database if
        # it exists
        options["interactive"] = False
        return super().handle(*test_labels, **options)

This works by intercepting the normal handle() method to first always set the interactive option to False. This is the same as always passing the --noinput command line flag, the documented way of forcing a database rebuild.

Fin

Hope this saves you some time from stalled test runs,

—Adam


Working on a Django project? Check out my book Speed Up Your Django Tests which covers loads of best practices so you can write faster, more accurate tests.


Subscribe via RSS, Twitter, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: django