Andrew Pinkham
unread,Feb 19, 2015, 12:07:17 PM2/19/15Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to django...@googlegroups.com
I am learning all sorts of things about Django's testing system (instead of actually getting work done).
The database schema is actually created via a call create_test_db() called on line 366 of setup_databases() in DiscoverRunner in django/test/runner.py. It's within this function, found in django/db/backends/base/creation.py, that migrate is called on available apps in Installed_Apps (via call_command!).
I was under the impression that code provided by TransactionTestCase was where the test database was (re-)created and destroyed throughout the lifetime of the test suite. As it turns out, while the code in TransactionTestCase loads and flushes data, it never touches the schema of the database (afaik).
This makes sense, as it seriously speeds up testing, as database creation is expensive.
Turns out, by simply overriding setUp and tearDown to use call_command with migrate, I can create the schema I desire.
# override/tests.py
from django.db import connections
from django.test import TestCase, override_settings, modify_settings
from django.core.management import call_command
@override_settings(
ROOT_URLCONF='override.urls')
@modify_settings(
INSTALLED_APPS={'prepend': {'override'}})
class OverrideTests(TestCase):
def setUp(self):
super().setUp()
for db in connections:
call_command(
'migrate',
'override',
verbosity=0,
interactive=False,
database=db,
test_flush=True)
def tearDown(self):
for db in connections:
call_command(
'migrate',
'override',
'zero',
verbosity=0,
interactive=False,
database=db,
test_flush=True)
super().tearDown()
This is, of course, quite slow, as each of my tests results in a database schema change.
I'm thus trying to get this working with setUpClass and tearDownClass.
@classmethod
def setUpClass(cls):
super().setUpClass()
for db in connections:
call_command(
'migrate',
'override',
verbosity=0,
interactive=False,
database=db,
test_flush=True)
@classmethod
def tearDownClass(cls):
for db in connections:
call_command(
'migrate',
'override',
'zero',
verbosity=0,
interactive=False,
database=db,
test_flush=True)
super().tearDownClass()
My understanding of TransactionTestCase (and the interaction with the decorators) makes me think this is possible, but at the moment, I'm getting the following error:
django.core.management.base.CommandError: App 'override' does not have migrations (you cannot selectively sync unmigrated apps)
I am also uncertain if this is a good idea, as I'm not clear as to whether TestCase will flush the data in the unexpected table (ie: will tests methods still be isolated?).
Any help or ideas welcome.
Andrew