mirror of
https://github.com/django/django.git
synced 2025-08-04 19:08:28 +00:00
Refs #25746 -- Added a test utility to isolate inlined model registration.
Thanks to Tim for the review.
This commit is contained in:
parent
b2cddeaaf4
commit
7bb373e309
4 changed files with 226 additions and 3 deletions
|
@ -303,3 +303,117 @@ purpose.
|
|||
|
||||
Support for running tests in parallel and the ``--parallel`` option were
|
||||
added.
|
||||
|
||||
Tips for writing tests
|
||||
----------------------
|
||||
|
||||
.. highlight:: python
|
||||
|
||||
Isolating model registration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To avoid polluting the global :attr:`~django.apps.apps` registry and prevent
|
||||
unnecessary table creation, models defined in a test method should be bound to
|
||||
a temporary ``Apps`` instance::
|
||||
|
||||
from django.apps.registry import Apps
|
||||
from django.db import models
|
||||
from django.test import SimpleTestCase
|
||||
|
||||
class TestModelDefinition(SimpleTestCase):
|
||||
def test_model_definition(self):
|
||||
test_apps = Apps(['app_label'])
|
||||
|
||||
class TestModel(models.Model):
|
||||
class Meta:
|
||||
apps = test_apps
|
||||
...
|
||||
|
||||
.. function:: django.test.utils.isolate_apps(*app_labels, attr_name=None, kwarg_name=None)
|
||||
|
||||
.. versionadded:: 1.10
|
||||
|
||||
Since this pattern involves a lot of boilerplate, Django provides the
|
||||
:func:`~django.test.utils.isolate_apps` decorator. It's used like this::
|
||||
|
||||
from django.db import models
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import isolate_apps
|
||||
|
||||
class TestModelDefinition(SimpleTestCase):
|
||||
@isolate_apps('app_label')
|
||||
def test_model_definition(self):
|
||||
class TestModel(models.Model):
|
||||
pass
|
||||
...
|
||||
|
||||
.. admonition:: Setting ``app_label``
|
||||
|
||||
Models defined in a test method with no explicit
|
||||
:attr:`~django.db.models.Options.app_label` are automatically assigned the
|
||||
label of the app in which their test class is located.
|
||||
|
||||
In order to make sure the models defined within the context of
|
||||
:func:`~django.test.utils.isolate_apps` instances are correctly
|
||||
installed, you should pass the set of targeted ``app_label`` as arguments:
|
||||
|
||||
.. snippet::
|
||||
:filename: tests/app_label/tests.py
|
||||
|
||||
from django.db import models
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import isolate_apps
|
||||
|
||||
class TestModelDefinition(SimpleTestCase):
|
||||
@isolate_apps('app_label', 'other_app_label')
|
||||
def test_model_definition(self):
|
||||
# This model automatically receives app_label='app_label'
|
||||
class TestModel(models.Model):
|
||||
pass
|
||||
|
||||
class OtherAppModel(models.Model):
|
||||
class Meta:
|
||||
app_label = 'other_app_label'
|
||||
...
|
||||
|
||||
The decorator can also be applied to classes::
|
||||
|
||||
from django.db import models
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import isolate_apps
|
||||
|
||||
@isolate_apps('app_label')
|
||||
class TestModelDefinition(SimpleTestCase):
|
||||
def test_model_definition(self):
|
||||
class TestModel(models.Model):
|
||||
pass
|
||||
...
|
||||
|
||||
The temporary ``Apps`` instance used to isolate model registration can be
|
||||
retrieved as an attribute when used as a class decorator by using the
|
||||
``attr_name`` parameter::
|
||||
|
||||
from django.db import models
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import isolate_apps
|
||||
|
||||
@isolate_apps('app_label', attr_name='apps')
|
||||
class TestModelDefinition(SimpleTestCase):
|
||||
def test_model_definition(self):
|
||||
class TestModel(models.Model):
|
||||
pass
|
||||
self.assertIs(self.apps.get_model('app_label', 'TestModel'), TestModel)
|
||||
|
||||
Or as an argument on the test method when used as a method decorator by using
|
||||
the ``kwarg_name`` parameter::
|
||||
|
||||
from django.db import models
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import isolate_apps
|
||||
|
||||
class TestModelDefinition(SimpleTestCase):
|
||||
@isolate_apps('app_label', kwarg_name='apps')
|
||||
def test_model_definition(self, apps):
|
||||
class TestModel(models.Model):
|
||||
pass
|
||||
self.assertIs(apps.get_model('app_label', 'TestModel'), TestModel)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue