Persisting Django’s Test Database
After running Django unittests, it may sometimes be useful to manually inspect the test database after unittests are complete. I was working on a complicated network model, trying to resolve an elusive bug in a unittest, and in this specific instance, I thought running a manually written SQL query would be a bit more helpful than dealing with Django’s ORM. Since most people don’t really care about the test database, Django’s unittest framework is understandably hard-coded to destroy it after the tests have ran. Although there’s no simply flag to disable this, after digging around in the code, I found it’s relatively easy enough to change with a couple class method overrides.
First, for convenience, I define a PERSIST_TEST_DATABASE = 1 flag in my settings.py.
Then, my tests.py takes the general form:
from django.conf import settings from django.test import TestCase if settings.PERSIST_TEST_DATABASE: # Disable destruction of the test database. from django.db import transaction, connection, connections, DEFAULT_DB_ALIAS from django.test.testcases import restore_transaction_methods, connections_support_transactions connection.creation.destroy_test_db = lambda *args, **kwargs: None class Test(TestCase): def _fixture_teardown(self): if not settings.PERSIST_TEST_DATABASE or not connections_support_transactions(): return super(TestCase, self)._fixture_teardown() # If the test case has a multi_db=True flag, teardown all databases. # Otherwise, just teardown default. if getattr(self, 'multi_db', False): databases = connections else: databases = [DEFAULT_DB_ALIAS] restore_transaction_methods() for db in databases: transaction.commit(using=db) transaction.leave_transaction_management(using=db)
My two overrides are connection.creation.destroy_test_db, which I completely disable, and TestCase._fixture_teardown, which is essentially the same as the original, but tweaked to commit instead of rollback the transaction.
Filed under: Django, Python, Uncategorized
Leave a Reply