Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added TestCase.settings context manager to easily override settings i…

…n test methods.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16165 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 0dc6420b3ebddd7bc2a0059b225d54ac19d4d901 1 parent 21027a0
@jezdez jezdez authored
View
19 django/test/testcases.py
@@ -2,11 +2,12 @@
import re
import sys
+from contextlib import contextmanager
from functools import wraps
from urlparse import urlsplit, urlunsplit
from xml.dom.minidom import parseString, Node
-from django.conf import settings
+from django.conf import settings, UserSettingsHolder
from django.core import mail
from django.core.management import call_command
from django.core.signals import request_started
@@ -341,6 +342,22 @@ def restore_warnings_state(self):
"""
restore_warnings_state(self._warnings_state)
+ @contextmanager
+ def settings(self, **options):
+ """
+ A context manager that temporarily sets a setting and reverts
+ back to the original value when exiting the context.
+ """
+ old_wrapped = settings._wrapped
+ override = UserSettingsHolder(settings._wrapped)
+ try:
+ for key, new_value in options.items():
+ setattr(override, key, new_value)
+ settings._wrapped = override
+ yield
+ finally:
+ settings._wrapped = old_wrapped
+
def assertRedirects(self, response, expected_url, status_code=302,
target_status_code=200, host=None, msg_prefix=''):
"""Asserts that a response redirected to a specific URL, and that the
View
25 docs/topics/testing.txt
@@ -1351,6 +1351,31 @@ For example::
This test case will flush *all* the test databases before running
``testIndexPageView``.
+Overriding settings
+~~~~~~~~~~~~~~~~~~~
+
+.. method:: TestCase.settings
+
+.. versionadded:: 1.4
+
+For testing purposes it's often useful to change a setting temporarily
+and revert to the original value after running the testing code. For
+this use case Django provides a standard `Python context manager`_
+:meth:`~django.test.TestCase.settings`, which can be used like this::
+
+ from django.test import TestCase
+
+ class LoginTestCase(TestCase):
+ def test_overriding_settings(self):
+ with self.settings(LOGIN_URL='/other/login/'):
+ response = self.client.get('/sekrit/')
+ self.assertRedirects(response, '/other/login/?next=/sekrit/')
+
+This example will override the :setting:`LOGIN_URL` setting for the code
+in the ``with`` block and reset its value to the previous state afterwards.
+
+.. _`Python context manager`: http://www.python.org/dev/peps/pep-0343/
+
Emptying the test outbox
~~~~~~~~~~~~~~~~~~~~~~~~
View
30 tests/regressiontests/settings_tests/tests.py
@@ -1,8 +1,31 @@
from django.conf import settings
-from django.utils import unittest
+from django.test import TestCase
+class SettingsTests(TestCase):
-class SettingsTests(unittest.TestCase):
+ def test_override(self):
+ settings.TEST = 'test'
+ self.assertEqual('test', settings.TEST)
+ with self.settings(TEST='override'):
+ self.assertEqual('override', settings.TEST)
+ self.assertEqual('test', settings.TEST)
+ del settings.TEST
+
+ def test_override_change(self):
+ settings.TEST = 'test'
+ self.assertEqual('test', settings.TEST)
+ with self.settings(TEST='override'):
+ self.assertEqual('override', settings.TEST)
+ settings.TEST = 'test2'
+ self.assertEqual('test', settings.TEST)
+ del settings.TEST
+
+ def test_override_doesnt_leak(self):
+ self.assertRaises(AttributeError, getattr, settings, 'TEST')
+ with self.settings(TEST='override'):
+ self.assertEqual('override', settings.TEST)
+ settings.TEST = 'test'
+ self.assertRaises(AttributeError, getattr, settings, 'TEST')
#
# Regression tests for #10130: deleting settings.
@@ -18,7 +41,8 @@ def test_settings_delete_wrapped(self):
self.assertRaises(TypeError, delattr, settings, '_wrapped')
-class TrailingSlashURLTests(unittest.TestCase):
+
+class TrailingSlashURLTests(TestCase):
settings_module = settings
def setUp(self):
Please sign in to comment.
Something went wrong with that request. Please try again.