summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2013-06-11 22:56:09 +0200
committerAymeric Augustin <aymeric.augustin@m4x.org>2013-06-12 20:01:41 +0200
commit55cbd65985bfad02512a64a4cb8468140f15ee84 (patch)
treeab3e850489557ee7faf6f2ba2913ce2b2021729a /docs
parent0938970491eee41ccde11bf3efe5b307ced8dba6 (diff)
Fixed #20579 -- Improved TransactionTestCase.available_apps.
Also moved its documentation to the 'advanced' section. It doesn't belong to the 'overview'. Same for TransactionTestCase.reset_sequences. When available_apps is set, after a TransactionTestCase, the database is now totally empty. post_syncdb is fired at the beginning of the next TransactionTestCase. Refs #20483.
Diffstat (limited to 'docs')
-rw-r--r--docs/topics/testing/advanced.txt74
-rw-r--r--docs/topics/testing/overview.txt80
2 files changed, 90 insertions, 64 deletions
diff --git a/docs/topics/testing/advanced.txt b/docs/topics/testing/advanced.txt
index b7f49d2b97..8f7f093901 100644
--- a/docs/topics/testing/advanced.txt
+++ b/docs/topics/testing/advanced.txt
@@ -155,6 +155,80 @@ If there are any circular dependencies in the
:setting:`TEST_DEPENDENCIES` definition, an ``ImproperlyConfigured``
exception will be raised.
+Advanced features of ``TransactionTestCase``
+============================================
+
+.. currentmodule:: django.test
+
+.. attribute:: TransactionTestCase.available_apps
+
+ .. versionadded:: 1.6
+
+ .. warning::
+
+ This attribute is a private API. It may be changed or removed without
+ a deprecation period in the future, for instance to accomodate changes
+ in application loading.
+
+ It's used to optimize Django's own test suite, which contains hundreds
+ of models but no relations between models in different applications.
+
+ By default, ``available_apps`` is set to ``None``. After each test, Django
+ calls :djadmin:`flush` to reset the database state. This empties all tables
+ and emits the :data:`~django.db.models.signals.post_syncdb` signal, which
+ re-creates one content type and three permissions for each model. This
+ operation gets expensive proportionally to the number of models.
+
+ Setting ``available_apps`` to a list of applications instructs Django to
+ behave as if only the models from these applications were available. The
+ behavior of ``TransactionTestCase`` changes as follows:
+
+ - :data:`~django.db.models.signals.post_syncdb` is fired before each
+ test to create the content types and permissions for each model in
+ available apps, in case they're missing.
+ - After each test, Django empties only tables corresponding to models in
+ available apps. However, at the database level, truncation may cascade to
+ related models in unavailable apps. Furthermore
+ :data:`~django.db.models.signals.post_syncdb` isn't fired; it will be
+ fired by the next ``TransactionTestCase``, after the correct set of
+ applications is selected.
+
+ Since the database isn't fully flushed, if a test creates instances of
+ models not included in ``available_apps``, they will leak and they may
+ cause unrelated tests to fail. Be careful with tests that use sessions;
+ the default session engine stores them in the database.
+
+ Since :data:`~django.db.models.signals.post_syncdb` isn't emitted after
+ flushing the database, its state after a ``TransactionTestCase`` isn't the
+ same as after a ``TestCase``: it's missing the rows created by listeners
+ to :data:`~django.db.models.signals.post_syncdb`. Considering the
+ :ref:`order in which tests are executed <order-of-tests>`, this isn't an
+ issue, provided either all ``TransactionTestCase`` in a given test suite
+ declare ``available_apps``, or none of them.
+
+ ``available_apps`` is mandatory in Django's own test suite.
+
+.. attribute:: TransactionTestCase.reset_sequences
+
+ .. versionadded:: 1.5
+
+ Setting ``reset_sequences = True`` on a ``TransactionTestCase`` will make
+ sure sequences are always reset before the test run::
+
+ class TestsThatDependsOnPrimaryKeySequences(TransactionTestCase):
+ reset_sequences = True
+
+ def test_animal_pk(self):
+ lion = Animal.objects.create(name="lion", sound="roar")
+ # lion.pk is guaranteed to always be 1
+ self.assertEqual(lion.pk, 1)
+
+ Unless you are explicitly testing primary keys sequence numbers, it is
+ recommended that you do not hard code primary key values in tests.
+
+ Using ``reset_sequences = True`` will slow down the test, since the primary
+ key reset is an relatively expensive database operation.
+
Running tests outside the test runner
=====================================
diff --git a/docs/topics/testing/overview.txt b/docs/topics/testing/overview.txt
index 6f73f7bbb5..8268051a36 100644
--- a/docs/topics/testing/overview.txt
+++ b/docs/topics/testing/overview.txt
@@ -213,6 +213,8 @@ advanced settings.
The :ref:`advanced multi-db testing topics <topics-testing-advanced-multidb>`.
+.. _order-of-tests:
+
Order in which tests are executed
---------------------------------
@@ -908,8 +910,8 @@ TransactionTestCase
.. class:: TransactionTestCase()
-Django ``TestCase`` classes make use of database transaction facilities, if
-available, to speed up the process of resetting the database to a known state
+Django's ``TestCase`` class (described below) makes use of database transaction
+facilities to speed up the process of resetting the database to a known state
at the beginning of each test. A consequence of this, however, is that the
effects of transaction commit and rollback cannot be tested by a Django
``TestCase`` class. If your test requires testing of such transactional
@@ -927,9 +929,9 @@ to test the effects of commit and rollback:
Instead, it encloses the test code in a database transaction that is rolled
back at the end of the test. Both explicit commits like
``transaction.commit()`` and implicit ones that may be caused by
- ``Model.save()`` are replaced with a ``nop`` operation. This guarantees that
- the rollback at the end of the test restores the database to its initial
- state.
+ ``transaction.atomic()`` are replaced with a ``nop`` operation. This
+ guarantees that the rollback at the end of the test restores the database to
+ its initial state.
When running on a database that does not support rollback (e.g. MySQL with the
MyISAM storage engine), ``TestCase`` falls back to initializing the database
@@ -940,22 +942,21 @@ to test the effects of commit and rollback:
While ``commit`` and ``rollback`` operations still *appear* to work when
used in ``TestCase``, no actual commit or rollback will be performed by the
database. This can cause your tests to pass or fail unexpectedly. Always
- use ``TransactionalTestCase`` when testing transactional behavior.
-
-.. note::
+ use ``TransactionTestCase`` when testing transactional behavior.
- .. versionchanged:: 1.5
+.. versionchanged:: 1.5
- Prior to 1.5, ``TransactionTestCase`` flushed the database tables *before*
- each test. In Django 1.5, this is instead done *after* the test has been run.
+ Prior to 1.5, :class:`~django.test.TransactionTestCase` flushed the
+ database tables *before* each test. In Django 1.5, this is instead done
+ *after* the test has been run.
When the flush took place before the test, it was guaranteed that primary
key values started at one in :class:`~django.test.TransactionTestCase`
tests.
- Tests should not depend on this behavior, but for legacy tests that do, the
- :attr:`~TransactionTestCase.reset_sequences` attribute can be used until
- the test has been properly updated.
+ Tests should not depend on this behavior, but for legacy tests that do,
+ the :attr:`~TransactionTestCase.reset_sequences` attribute can be used
+ until the test has been properly updated.
.. versionchanged:: 1.5
@@ -964,55 +965,6 @@ to test the effects of commit and rollback:
``TransactionTestCase`` inherits from :class:`~django.test.SimpleTestCase`.
-.. attribute:: TransactionTestCase.reset_sequences
-
- .. versionadded:: 1.5
-
- Setting ``reset_sequences = True`` on a ``TransactionTestCase`` will make
- sure sequences are always reset before the test run::
-
- class TestsThatDependsOnPrimaryKeySequences(TransactionTestCase):
- reset_sequences = True
-
- def test_animal_pk(self):
- lion = Animal.objects.create(name="lion", sound="roar")
- # lion.pk is guaranteed to always be 1
- self.assertEqual(lion.pk, 1)
-
- Unless you are explicitly testing primary keys sequence numbers, it is
- recommended that you do not hard code primary key values in tests.
-
- Using ``reset_sequences = True`` will slow down the test, since the primary
- key reset is an relatively expensive database operation.
-
-.. attribute:: TransactionTestCase.available_apps
-
- .. warning::
-
- This attribute is a private API. It may be changed or removed without
- a deprecation period in the future, for instance to accomodate changes
- in application loading.
-
- It's used to optimize Django's own test suite, which contains hundreds
- of models but no relations between models in different applications.
-
- .. versionadded:: 1.6
-
- By default, ``available_apps`` is set to ``None`` and has no effect.
- Setting it to a list of applications tells Django to behave as if only the
- models from these applications were available:
-
- - Before each test, Django creates content types and permissions only for
- these models.
- - After each test, Django flushes only the corresponding tables. However,
- at the database level, truncation may cascade to other related models,
- even if they aren't in ``available_apps``.
-
- Since the database isn't fully flushed, if a test creates instances of
- models not included in ``available_apps``, they will leak and they may
- cause unrelated tests to fail. Be careful with tests that use sessions;
- the default session engine stores them in the database.
-
TestCase
~~~~~~~~
@@ -1495,7 +1447,7 @@ Emptying the test outbox
~~~~~~~~~~~~~~~~~~~~~~~~
If you use any of Django's custom ``TestCase`` classes, the test runner will
-clear thecontents of the test email outbox at the start of each test case.
+clear the contents of the test email outbox at the start of each test case.
For more detail on email services during tests, see `Email services`_ below.