diff --git a/AUTHORS b/AUTHORS
index 472d53c999..aaa6329ea4 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -154,6 +154,7 @@ answer newbie questions, and generally made Django that much better:
Antonio Cavedoni
cedric@terramater.net
Chris Chamberlin
+ Greg Chapple
Amit Chakradeo
ChaosKCW
Kowito Charoenratchatabhan
diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
index 72fea241dc..13d4789ca2 100644
--- a/django/db/backends/creation.py
+++ b/django/db/backends/creation.py
@@ -449,7 +449,7 @@ class BaseDatabaseCreation(object):
return test_database_name
- def destroy_test_db(self, old_database_name, verbosity=1):
+ def destroy_test_db(self, old_database_name, verbosity=1, keepdb=False):
"""
Destroy a test database, prompting the user for confirmation if the
database already exists.
@@ -458,12 +458,18 @@ class BaseDatabaseCreation(object):
test_database_name = self.connection.settings_dict['NAME']
if verbosity >= 1:
test_db_repr = ''
+ action = 'Destroying'
if verbosity >= 2:
test_db_repr = " ('%s')" % test_database_name
- print("Destroying test database for alias '%s'%s..." % (
- self.connection.alias, test_db_repr))
+ if keepdb:
+ action = 'Preserving'
+ print("%s test database for alias '%s'%s..." % (
+ action, self.connection.alias, test_db_repr))
- self._destroy_test_db(test_database_name, verbosity)
+ # if we want to preserve the database
+ # skip the actual destroying piece.
+ if not keepdb:
+ self._destroy_test_db(test_database_name, verbosity)
def _destroy_test_db(self, test_database_name, verbosity):
"""
diff --git a/django/test/runner.py b/django/test/runner.py
index 68671e6525..226238a59a 100644
--- a/django/test/runner.py
+++ b/django/test/runner.py
@@ -124,8 +124,8 @@ class DiscoverRunner(object):
"""
old_names, mirrors = old_config
for connection, old_name, destroy in old_names:
- if destroy and not self.keepdb:
- connection.creation.destroy_test_db(old_name, self.verbosity)
+ if destroy:
+ connection.creation.destroy_test_db(old_name, self.verbosity, self.keepdb)
def teardown_test_environment(self, **kwargs):
unittest.removeHandler()
diff --git a/docs/topics/testing/advanced.txt b/docs/topics/testing/advanced.txt
index 046f663672..13041c1945 100644
--- a/docs/topics/testing/advanced.txt
+++ b/docs/topics/testing/advanced.txt
@@ -485,7 +485,7 @@ django.db.connection.creation
The creation module of the database backend also provides some utilities that
can be useful during testing.
-.. function:: create_test_db([verbosity=1, autoclobber=False])
+.. function:: create_test_db([verbosity=1, autoclobber=False, keepdb=False])
Creates a new test database and runs ``migrate`` against it.
@@ -501,13 +501,19 @@ can be useful during testing.
* If autoclobber is ``True``, the database will be destroyed
without consulting the user.
+ ``keepdb`` determines if the test run should use an existing
+ database, or create a new one. If ``True``, the existing
+ database will be used, or created if not present. If ``False``,
+ a new database will be created, prompting the user to remove
+ the existing one, if present.
+
Returns the name of the test database that it created.
``create_test_db()`` has the side effect of modifying the value of
:setting:`NAME` in :setting:`DATABASES` to match the name of the test
database.
-.. function:: destroy_test_db(old_database_name, [verbosity=1])
+.. function:: destroy_test_db(old_database_name, [verbosity=1, keepdb=False])
Destroys the database whose name is the value of :setting:`NAME` in
:setting:`DATABASES`, and sets :setting:`NAME` to the value of
@@ -516,6 +522,9 @@ can be useful during testing.
The ``verbosity`` argument has the same behavior as for
:class:`~django.test.runner.DiscoverRunner`.
+ If the ``keepdb`` argument is ``True``, then the connection to the
+ database will be closed, but the database will not be destroyed.
+
.. _topics-testing-code-coverage:
Integration with coverage.py
diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py
index 6de53b8283..bb46e53fd3 100644
--- a/tests/test_runner/tests.py
+++ b/tests/test_runner/tests.py
@@ -309,7 +309,7 @@ class AliasedDatabaseTeardownTest(unittest.TestCase):
old_create_test_db = DatabaseCreation.create_test_db
try:
destroyed_names = []
- DatabaseCreation.destroy_test_db = lambda self, old_database_name, verbosity=1: destroyed_names.append(old_database_name)
+ DatabaseCreation.destroy_test_db = lambda self, old_database_name, verbosity=1, keepdb=False: destroyed_names.append(old_database_name)
DatabaseCreation.create_test_db = lambda self, verbosity=1, autoclobber=False, keepdb=False: self._get_test_db_name()
db.connections = db.ConnectionHandler({