Fixed #25388 -- Added an option to allow disabling of migrations during test database creation.

This commit is contained in:
Jon Dufresne 2019-11-12 19:49:09 -08:00 committed by Mariusz Felisiak
parent 3e5b349535
commit f5ebdfce5c
6 changed files with 70 additions and 18 deletions

View File

@ -61,16 +61,17 @@ class BaseDatabaseCreation:
settings.DATABASES[self.connection.alias]["NAME"] = test_database_name
self.connection.settings_dict["NAME"] = test_database_name
# We report migrate messages at one level lower than that requested.
# This ensures we don't get flooded with messages during testing
# (unless you really ask to be flooded).
call_command(
'migrate',
verbosity=max(verbosity - 1, 0),
interactive=False,
database=self.connection.alias,
run_syncdb=True,
)
if self.connection.settings_dict['TEST']['MIGRATE']:
# We report migrate messages at one level lower than that
# requested. This ensures we don't get flooded with messages during
# testing (unless you really ask to be flooded).
call_command(
'migrate',
verbosity=max(verbosity - 1, 0),
interactive=False,
database=self.connection.alias,
run_syncdb=True,
)
# We then serialize the current state of the database into a string
# and store it on the connection. This slightly horrific process is so people

View File

@ -194,8 +194,15 @@ class ConnectionHandler:
raise ConnectionDoesNotExist("The connection %s doesn't exist" % alias)
test_settings = conn.setdefault('TEST', {})
for key in ['CHARSET', 'COLLATION', 'NAME', 'MIRROR']:
test_settings.setdefault(key, None)
default_test_settings = [
('CHARSET', None),
('COLLATION', None),
('MIGRATE', True),
('MIRROR', None),
('NAME', None),
]
for key, value in default_test_settings:
test_settings.setdefault(key, value)
def __getitem__(self, alias):
if hasattr(self._connections, alias):

View File

@ -1371,8 +1371,9 @@ Preserves the test database between test runs. This has the advantage of
skipping both the create and destroy actions which can greatly decrease the
time to run tests, especially those in a large test suite. If the test database
does not exist, it will be created on the first run and then preserved for each
subsequent run. Any unapplied migrations will also be applied to the test
database before running the test suite.
subsequent run. Unless the :setting:`MIGRATE <TEST_MIGRATE>` test setting is
``False``, any unapplied migrations will also be applied to the test database
before running the test suite.
.. django-admin-option:: --reverse, -r

View File

@ -739,6 +739,17 @@ The creation-order dependencies of the database. See the documentation
on :ref:`controlling the creation order of test databases
<topics-testing-creation-dependencies>` for details.
.. setting:: TEST_MIGRATE
``MIGRATE``
^^^^^^^^^^^
.. versionadded:: 3.1
Default: ``True``
When set to ``False``, migrations won't run when creating the test database.
.. setting:: TEST_MIRROR
``MIRROR``
@ -2034,9 +2045,11 @@ automatically create the package if it doesn't already exist.
When you supply ``None`` as a value for an app, Django will consider the app as
an app without migrations regardless of an existing ``migrations`` submodule.
This can be used, for example, in a test settings file to skip migrations while
testing (tables will still be created for the apps' models). If this is used in
your general project settings, remember to use the :option:`migrate
--run-syncdb` option if you want to create tables for the app.
testing (tables will still be created for the apps' models). To disable
migrations for all apps during tests, you can set the
:setting:`MIGRATE <TEST_MIGRATE>` to ``True`` instead. If ``MIGRATION_MODULES``
is used in your general project settings, remember to use the
:option:`migrate --run-syncdb` option if you want to create tables for the app.
.. setting:: MONTH_DAY_FORMAT

View File

@ -237,6 +237,9 @@ Tests
allow running a test without collecting the result and catching exceptions.
This can be used to support running tests under a debugger.
* The new :setting:`MIGRATE <TEST_MIGRATE>` test database setting allows
disabling of migrations during a test database creation.
URLs
~~~~

View File

@ -1,6 +1,7 @@
import copy
from unittest import mock
from django.db import DEFAULT_DB_ALIAS, connections
from django.db import DEFAULT_DB_ALIAS, connection, connections
from django.db.backends.base.creation import (
TEST_DATABASE_PREFIX, BaseDatabaseCreation,
)
@ -40,3 +41,29 @@ class TestDbSignatureTests(SimpleTestCase):
test_connection.settings_dict['TEST'] = {'NAME': test_name}
signature = BaseDatabaseCreation(test_connection).test_db_signature()
self.assertEqual(signature[3], test_name)
@mock.patch.object(connection, 'ensure_connection')
@mock.patch('django.core.management.commands.migrate.Command.handle', return_value=None)
class TestDbCreationTests(SimpleTestCase):
def test_migrate_test_setting_false(self, mocked_migrate, mocked_ensure_connection):
creation = connection.creation_class(connection)
saved_settings = copy.deepcopy(connection.settings_dict)
try:
connection.settings_dict['TEST']['MIGRATE'] = False
with mock.patch.object(creation, '_create_test_db'):
creation.create_test_db(verbosity=0, autoclobber=True, serialize=False)
mocked_migrate.assert_not_called()
finally:
connection.settings_dict = saved_settings
def test_migrate_test_setting_true(self, mocked_migrate, mocked_ensure_connection):
creation = connection.creation_class(connection)
saved_settings = copy.deepcopy(connection.settings_dict)
try:
connection.settings_dict['TEST']['MIGRATE'] = True
with mock.patch.object(creation, '_create_test_db'):
creation.create_test_db(verbosity=0, autoclobber=True, serialize=False)
mocked_migrate.assert_called_once()
finally:
connection.settings_dict = saved_settings