summaryrefslogtreecommitdiff
path: root/django/test
diff options
context:
space:
mode:
authorRamiro Morales <cramm0@gmail.com>2012-07-24 17:24:16 -0300
committerRamiro Morales <cramm0@gmail.com>2012-07-24 17:24:16 -0300
commitf758bdab5eec3e615598948dd5bcf9bb7b910c9d (patch)
treef6a8161010c629fcb22a561dac307737251ce530 /django/test
parent38ce709fe44ebf37e6c8531451eab98fe0a552a0 (diff)
Fixed #18271 -- Changed stage at which TransactionTestCase flushes DB tables.
Previously, the flush was done before the test case execution and now it is performed after it. Other changes to the testing infrastructure include: * TransactionTestCase now doesn't reset autoincrement sequences either (previous behavior can achieved by using `reset_sequences`.) With this, no implicit such reset is performed by any of the provided TestCase classes. * New ordering of test cases: All unittest tes cases are run first and doctests are run at the end. THse changes could be backward-incompatible with test cases that relied on some kind of state being preserved between tests. Please read the relevant sections of the release notes and testing documentation for further details. Thanks Andreas Pelme for the initial patch. Karen Tracey and Anssi Kääriäinen for the feedback and Anssi for reviewing. This also fixes #12408.
Diffstat (limited to 'django/test')
-rw-r--r--django/test/simple.py4
-rw-r--r--django/test/testcases.py62
2 files changed, 45 insertions, 21 deletions
diff --git a/django/test/simple.py b/django/test/simple.py
index 4f05284543..bf0219d53f 100644
--- a/django/test/simple.py
+++ b/django/test/simple.py
@@ -5,7 +5,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.db.models import get_app, get_apps
from django.test import _doctest as doctest
from django.test.utils import setup_test_environment, teardown_test_environment
-from django.test.testcases import OutputChecker, DocTestRunner, TestCase
+from django.test.testcases import OutputChecker, DocTestRunner
from django.utils import unittest
from django.utils.importlib import import_module
from django.utils.module_loading import module_has_submodule
@@ -263,7 +263,7 @@ class DjangoTestSuiteRunner(object):
for test in extra_tests:
suite.addTest(test)
- return reorder_suite(suite, (TestCase,))
+ return reorder_suite(suite, (unittest.TestCase,))
def setup_databases(self, **kwargs):
from django.db import connections, DEFAULT_DB_ALIAS
diff --git a/django/test/testcases.py b/django/test/testcases.py
index b9aae21e8e..b60188bf30 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -23,6 +23,7 @@ from django.core import mail
from django.core.exceptions import ValidationError, ImproperlyConfigured
from django.core.handlers.wsgi import WSGIHandler
from django.core.management import call_command
+from django.core.management.color import no_style
from django.core.signals import request_started
from django.core.servers.basehttp import (WSGIRequestHandler, WSGIServer,
WSGIServerException)
@@ -444,10 +445,15 @@ class SimpleTestCase(ut2.TestCase):
class TransactionTestCase(SimpleTestCase):
+
# The class we'll use for the test client self.client.
# Can be overridden in derived classes.
client_class = Client
+ # Subclasses can ask for resetting of auto increment sequence before each
+ # test case
+ reset_sequences = False
+
def _pre_setup(self):
"""Performs any pre-test setup. This includes:
@@ -462,22 +468,36 @@ class TransactionTestCase(SimpleTestCase):
self._urlconf_setup()
mail.outbox = []
+ def _reset_sequences(self, db_name):
+ conn = connections[db_name]
+ if conn.features.supports_sequence_reset:
+ sql_list = \
+ conn.ops.sequence_reset_by_name_sql(no_style(),
+ conn.introspection.sequence_list())
+ if sql_list:
+ try:
+ cursor = conn.cursor()
+ for sql in sql_list:
+ cursor.execute(sql)
+ except Exception:
+ transaction.rollback_unless_managed(using=db_name)
+ raise
+ transaction.commit_unless_managed(using=db_name)
+
def _fixture_setup(self):
- # If the test case has a multi_db=True flag, flush all databases.
- # Otherwise, just flush default.
- if getattr(self, 'multi_db', False):
- databases = connections
- else:
- databases = [DEFAULT_DB_ALIAS]
- for db in databases:
- call_command('flush', verbosity=0, interactive=False, database=db,
- skip_validation=True)
+ # If the test case has a multi_db=True flag, act on all databases.
+ # Otherwise, just on the default DB.
+ db_names = connections if getattr(self, 'multi_db', False) else [DEFAULT_DB_ALIAS]
+ for db_name in db_names:
+ # Reset sequences
+ if self.reset_sequences:
+ self._reset_sequences(db_name)
if hasattr(self, 'fixtures'):
# We have to use this slightly awkward syntax due to the fact
# that we're using *args and **kwargs together.
call_command('loaddata', *self.fixtures,
- **{'verbosity': 0, 'database': db, 'skip_validation': True})
+ **{'verbosity': 0, 'database': db_name, 'skip_validation': True})
def _urlconf_setup(self):
if hasattr(self, 'urls'):
@@ -534,7 +554,12 @@ class TransactionTestCase(SimpleTestCase):
conn.close()
def _fixture_teardown(self):
- pass
+ # If the test case has a multi_db=True flag, flush all databases.
+ # Otherwise, just flush default.
+ databases = connections if getattr(self, 'multi_db', False) else [DEFAULT_DB_ALIAS]
+ for db in databases:
+ call_command('flush', verbosity=0, interactive=False, database=db,
+ skip_validation=True, reset_sequences=False)
def _urlconf_teardown(self):
if hasattr(self, '_old_root_urlconf'):
@@ -808,22 +833,21 @@ class TestCase(TransactionTestCase):
if not connections_support_transactions():
return super(TestCase, self)._fixture_setup()
+ assert not self.reset_sequences, 'reset_sequences cannot be used on TestCase instances'
+
# If the test case has a multi_db=True flag, setup all databases.
# Otherwise, just use default.
- if getattr(self, 'multi_db', False):
- databases = connections
- else:
- databases = [DEFAULT_DB_ALIAS]
+ db_names = connections if getattr(self, 'multi_db', False) else [DEFAULT_DB_ALIAS]
- for db in databases:
- transaction.enter_transaction_management(using=db)
- transaction.managed(True, using=db)
+ for db_name in db_names:
+ transaction.enter_transaction_management(using=db_name)
+ transaction.managed(True, using=db_name)
disable_transaction_methods()
from django.contrib.sites.models import Site
Site.objects.clear_cache()
- for db in databases:
+ for db in db_names:
if hasattr(self, 'fixtures'):
call_command('loaddata', *self.fixtures,
**{