Kaydet (Commit) 415bd694 authored tarafından Russell Keith-Magee's avatar Russell Keith-Magee

Fixed #7521 -- Added the ability to customize ROOT_URLCONF for the duration of a…

Fixed #7521 -- Added the ability to customize ROOT_URLCONF for the duration of a TestCase. Thanks to Mark Fargas (telenieko) for his work on this patch.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@7805 bcc190cf-cafb-0310-a4f2-bffc1f526a37
üst 61898d86
......@@ -21,18 +21,14 @@ class TestForm(forms.Form):
class PreviewTests(TestCase):
urls = 'django.contrib.formtools.test_urls'
def setUp(self):
self._old_root_urlconf = settings.ROOT_URLCONF
settings.ROOT_URLCONF = 'django.contrib.formtools.test_urls'
# Create a FormPreview instance to share between tests
self.preview = preview.FormPreview(TestForm)
input_template = '<input type="hidden" name="%s" value="%s" />'
self.input = input_template % (self.preview.unused_name('stage'), "%d")
def tearDown(self):
settings.ROOT_URLCONF = self._old_root_urlconf
def test_unused_name(self):
"""
Verifies name mangling to get uniue field name.
......
......@@ -296,3 +296,8 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None):
kwargs = kwargs or {}
return iri_to_uri(u'/' + get_resolver(urlconf).reverse(viewname, *args, **kwargs))
def clear_url_caches():
global _resolver_cache
global _callable_cache
_resolver_cache.clear()
_callable_cache.clear()
......@@ -4,10 +4,12 @@ from urlparse import urlsplit, urlunsplit
from django.http import QueryDict
from django.db import transaction
from django.conf import settings
from django.core import mail
from django.core.management import call_command
from django.test import _doctest as doctest
from django.test.client import Client
from django.core.urlresolvers import clear_url_caches
normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)
......@@ -54,6 +56,8 @@ class TestCase(unittest.TestCase):
* Flushing the database.
* If the Test Case class has a 'fixtures' member, installing the
named fixtures.
* If the Test Case class has a 'urls' member, replace the
ROOT_URLCONF with it.
* Clearing the mail test outbox.
"""
call_command('flush', verbosity=0, interactive=False)
......@@ -61,6 +65,10 @@ class TestCase(unittest.TestCase):
# 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})
if hasattr(self, 'urls'):
self._old_root_urlconf = settings.ROOT_URLCONF
settings.ROOT_URLCONF = self.urls
clear_url_caches()
mail.outbox = []
def __call__(self, result=None):
......@@ -79,6 +87,23 @@ class TestCase(unittest.TestCase):
result.addError(self, sys.exc_info())
return
super(TestCase, self).__call__(result)
try:
self._post_teardown()
except (KeyboardInterrupt, SystemExit):
raise
except Exception:
import sys
result.addError(self, sys.exc_info())
return
def _post_teardown(self):
""" Performs any post-test things. This includes:
* Putting back the original ROOT_URLCONF if it was changed.
"""
if hasattr(self, '_old_root_urlconf'):
settings.ROOT_URLCONF = self._old_root_urlconf
clear_url_caches()
def assertRedirects(self, response, expected_url, status_code=302,
target_status_code=200, host=None):
......
......@@ -797,6 +797,37 @@ another test, or by the order of test execution.
.. _dumpdata documentation: ../django-admin/#dumpdata-appname-appname
.. _loaddata documentation: ../django-admin/#loaddata-fixture-fixture
URLconf configuration
~~~~~~~~~~~~~~~~~~~~~
**New in Django development version**
If your application provides views, you may want to include tests that
use the test client to exercise those views. However, an end user is free
to deploy the views in your application at any URL of their choosing.
This means that your tests can't rely upon the fact that your views will
be available at a particular URL.
In order to provide a reliable URL space for your test,
``django.test.TestCase`` provides the ability to customize the URLconf
configuration for the duration of the execution of a test suite.
If your ``TestCase`` instance defines an ``urls`` attribute, the
``TestCase`` will use the value of that attribute as the ``ROOT_URLCONF``
for the duration of that test.
For example::
from django.test import TestCase
class TestMyViews(TestCase):
urls = 'myapp.test_urls'
def testIndexPageView(self):
# Here you'd test your view using ``Client``.
This test case will use the contents of ``myapp.test_urls`` as the
URLconf for the duration of the test case.
Emptying the test outbox
~~~~~~~~~~~~~~~~~~~~~~~~
......
......@@ -318,3 +318,22 @@ class ExceptionTests(TestCase):
self.client.get("/test_client_regress/staff_only/")
except SuspiciousOperation:
self.fail("Staff should be able to visit this page")
# We need two different tests to check URLconf subsitution - one to check
# it was changed, and another one (without self.urls) to check it was reverted on
# teardown. This pair of tests relies upon the alphabetical ordering of test execution.
class UrlconfSubstitutionTests(TestCase):
urls = 'regressiontests.test_client_regress.urls'
def test_urlconf_was_changed(self):
"TestCase can enforce a custom URLConf on a per-test basis"
url = reverse('arg_view', args=['somename'])
self.assertEquals(url, '/arg_view/somename/')
# This test needs to run *after* UrlconfSubstitutionTests; the zz prefix in the
# name is to ensure alphabetical ordering.
class zzUrlconfSubstitutionTests(TestCase):
def test_urlconf_was_reverted(self):
"URLconf is reverted to original value after modification in a TestCase"
url = reverse('arg_view', args=['somename'])
self.assertEquals(url, '/test_client_regress/arg_view/somename/')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment