mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	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
This commit is contained in:
		| @@ -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/') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user