Fixed #21281 -- Made override_settings act at class level when used as a TestCase decorator.
This commit is contained in:
parent
8b77b64f1c
commit
d89f56dc4d
|
@ -161,6 +161,24 @@ class SimpleTestCase(unittest.TestCase):
|
||||||
_overridden_settings = None
|
_overridden_settings = None
|
||||||
_modified_settings = None
|
_modified_settings = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
if cls._overridden_settings:
|
||||||
|
cls._cls_overridden_context = override_settings(**cls._overridden_settings)
|
||||||
|
cls._cls_overridden_context.enable()
|
||||||
|
if cls._modified_settings:
|
||||||
|
cls._cls_modified_context = modify_settings(cls._modified_settings)
|
||||||
|
cls._cls_modified_context.enable()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
if hasattr(cls, '_cls_modified_context'):
|
||||||
|
cls._cls_modified_context.disable()
|
||||||
|
delattr(cls, '_cls_modified_context')
|
||||||
|
if hasattr(cls, '_cls_overridden_context'):
|
||||||
|
cls._cls_overridden_context.disable()
|
||||||
|
delattr(cls, '_cls_overridden_context')
|
||||||
|
|
||||||
def __call__(self, result=None):
|
def __call__(self, result=None):
|
||||||
"""
|
"""
|
||||||
Wrapper around default __call__ method to perform common Django test
|
Wrapper around default __call__ method to perform common Django test
|
||||||
|
@ -192,24 +210,18 @@ class SimpleTestCase(unittest.TestCase):
|
||||||
* If the class has a 'urls' attribute, replace ROOT_URLCONF with it.
|
* If the class has a 'urls' attribute, replace ROOT_URLCONF with it.
|
||||||
* Clearing the mail test outbox.
|
* Clearing the mail test outbox.
|
||||||
"""
|
"""
|
||||||
if self._overridden_settings:
|
|
||||||
self._overridden_context = override_settings(**self._overridden_settings)
|
|
||||||
self._overridden_context.enable()
|
|
||||||
if self._modified_settings:
|
|
||||||
self._modified_context = modify_settings(self._modified_settings)
|
|
||||||
self._modified_context.enable()
|
|
||||||
self.client = self.client_class()
|
self.client = self.client_class()
|
||||||
self._urlconf_setup()
|
self._urlconf_setup()
|
||||||
mail.outbox = []
|
mail.outbox = []
|
||||||
|
|
||||||
def _urlconf_setup(self):
|
def _urlconf_setup(self):
|
||||||
set_urlconf(None)
|
|
||||||
if hasattr(self, 'urls'):
|
if hasattr(self, 'urls'):
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"SimpleTestCase.urls is deprecated and will be removed in "
|
"SimpleTestCase.urls is deprecated and will be removed in "
|
||||||
"Django 2.0. Use @override_settings(ROOT_URLCONF=...) "
|
"Django 2.0. Use @override_settings(ROOT_URLCONF=...) "
|
||||||
"in %s instead." % self.__class__.__name__,
|
"in %s instead." % self.__class__.__name__,
|
||||||
RemovedInDjango20Warning, stacklevel=2)
|
RemovedInDjango20Warning, stacklevel=2)
|
||||||
|
set_urlconf(None)
|
||||||
self._old_root_urlconf = settings.ROOT_URLCONF
|
self._old_root_urlconf = settings.ROOT_URLCONF
|
||||||
settings.ROOT_URLCONF = self.urls
|
settings.ROOT_URLCONF = self.urls
|
||||||
clear_url_caches()
|
clear_url_caches()
|
||||||
|
@ -220,14 +232,10 @@ class SimpleTestCase(unittest.TestCase):
|
||||||
* Putting back the original ROOT_URLCONF if it was changed.
|
* Putting back the original ROOT_URLCONF if it was changed.
|
||||||
"""
|
"""
|
||||||
self._urlconf_teardown()
|
self._urlconf_teardown()
|
||||||
if self._modified_settings:
|
|
||||||
self._modified_context.disable()
|
|
||||||
if self._overridden_settings:
|
|
||||||
self._overridden_context.disable()
|
|
||||||
|
|
||||||
def _urlconf_teardown(self):
|
def _urlconf_teardown(self):
|
||||||
set_urlconf(None)
|
|
||||||
if hasattr(self, '_old_root_urlconf'):
|
if hasattr(self, '_old_root_urlconf'):
|
||||||
|
set_urlconf(None)
|
||||||
settings.ROOT_URLCONF = self._old_root_urlconf
|
settings.ROOT_URLCONF = self._old_root_urlconf
|
||||||
clear_url_caches()
|
clear_url_caches()
|
||||||
|
|
||||||
|
@ -1169,6 +1177,7 @@ class LiveServerTestCase(TransactionTestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
super(LiveServerTestCase, cls).setUpClass()
|
||||||
connections_override = {}
|
connections_override = {}
|
||||||
for conn in connections.all():
|
for conn in connections.all():
|
||||||
# If using in-memory sqlite databases, pass the connections to
|
# If using in-memory sqlite databases, pass the connections to
|
||||||
|
|
|
@ -919,3 +919,11 @@ to construct the "view on site" URL. This URL is now accessible using the
|
||||||
``FormMixin`` subclasses that override the ``get_form()`` method should make
|
``FormMixin`` subclasses that override the ``get_form()`` method should make
|
||||||
sure to provide a default value for the ``form_class`` argument since it's
|
sure to provide a default value for the ``form_class`` argument since it's
|
||||||
now optional.
|
now optional.
|
||||||
|
|
||||||
|
Overriding ``setUpClass`` / ``tearDownClass`` in test cases
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The decorators :func:`~django.test.override_settings` and
|
||||||
|
:func:`~django.test.modify_settings` now act at the class level when used as
|
||||||
|
class decorators. As a consequence, when overriding ``setUpClass()`` or
|
||||||
|
``tearDownClass()``, the ``super`` implementation should always be called.
|
||||||
|
|
|
@ -607,6 +607,25 @@ then you should use :class:`~django.test.TransactionTestCase` or
|
||||||
|
|
||||||
``SimpleTestCase`` inherits from ``unittest.TestCase``.
|
``SimpleTestCase`` inherits from ``unittest.TestCase``.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
``SimpleTestCase`` and its subclasses (e.g. ``TestCase``, ...) rely on
|
||||||
|
``setUpClass()`` and ``tearDownClass()`` to perform some class-wide
|
||||||
|
initialization (e.g. overriding settings). If you need to override those
|
||||||
|
methods, don't forget to call the ``super`` implementation::
|
||||||
|
|
||||||
|
class MyTestCase(TestCase):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super(cls, MyTestCase).setUpClass() # Call parent first
|
||||||
|
...
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
...
|
||||||
|
super(cls, MyTestCase).tearDownClass() # Call parent last
|
||||||
|
|
||||||
TransactionTestCase
|
TransactionTestCase
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -751,8 +770,8 @@ Then, add a ``LiveServerTestCase``-based test to your app's tests module
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
cls.selenium = WebDriver()
|
|
||||||
super(MySeleniumTests, cls).setUpClass()
|
super(MySeleniumTests, cls).setUpClass()
|
||||||
|
cls.selenium = WebDriver()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
|
|
|
@ -28,6 +28,7 @@ from django.middleware.csrf import CsrfViewMiddleware
|
||||||
from django.template import Template
|
from django.template import Template
|
||||||
from django.template.response import TemplateResponse
|
from django.template.response import TemplateResponse
|
||||||
from django.test import TestCase, TransactionTestCase, RequestFactory, override_settings
|
from django.test import TestCase, TransactionTestCase, RequestFactory, override_settings
|
||||||
|
from django.test.signals import setting_changed
|
||||||
from django.test.utils import IgnoreDeprecationWarningsMixin
|
from django.test.utils import IgnoreDeprecationWarningsMixin
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
@ -1144,8 +1145,12 @@ class FileBasedCacheTests(BaseCacheTests, TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(FileBasedCacheTests, self).setUp()
|
super(FileBasedCacheTests, self).setUp()
|
||||||
self.dirname = tempfile.mkdtemp()
|
self.dirname = tempfile.mkdtemp()
|
||||||
|
# Caches location cannot be modified through override_settings / modify_settings,
|
||||||
|
# hence settings are manipulated directly here and the setting_changed signal
|
||||||
|
# is triggered manually.
|
||||||
for cache_params in settings.CACHES.values():
|
for cache_params in settings.CACHES.values():
|
||||||
cache_params.update({'LOCATION': self.dirname})
|
cache_params.update({'LOCATION': self.dirname})
|
||||||
|
setting_changed.send(self.__class__, setting='CACHES', enter=False)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(FileBasedCacheTests, self).tearDown()
|
super(FileBasedCacheTests, self).tearDown()
|
||||||
|
|
|
@ -33,12 +33,14 @@ class FileUploadTests(TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
super(FileUploadTests, cls).setUpClass()
|
||||||
if not os.path.isdir(MEDIA_ROOT):
|
if not os.path.isdir(MEDIA_ROOT):
|
||||||
os.makedirs(MEDIA_ROOT)
|
os.makedirs(MEDIA_ROOT)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
shutil.rmtree(MEDIA_ROOT)
|
shutil.rmtree(MEDIA_ROOT)
|
||||||
|
super(FileUploadTests, cls).tearDownClass()
|
||||||
|
|
||||||
def test_simple_upload(self):
|
def test_simple_upload(self):
|
||||||
with open(__file__, 'rb') as fp:
|
with open(__file__, 'rb') as fp:
|
||||||
|
@ -494,12 +496,14 @@ class DirectoryCreationTests(TestCase):
|
||||||
"""
|
"""
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
super(DirectoryCreationTests, cls).setUpClass()
|
||||||
if not os.path.isdir(MEDIA_ROOT):
|
if not os.path.isdir(MEDIA_ROOT):
|
||||||
os.makedirs(MEDIA_ROOT)
|
os.makedirs(MEDIA_ROOT)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
shutil.rmtree(MEDIA_ROOT)
|
shutil.rmtree(MEDIA_ROOT)
|
||||||
|
super(DirectoryCreationTests, cls).tearDownClass()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.obj = FileModel()
|
self.obj = FileModel()
|
||||||
|
|
|
@ -855,6 +855,7 @@ class SMTPBackendTests(BaseEmailBackendTests, SimpleTestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
super(SMTPBackendTests, cls).setUpClass()
|
||||||
cls.server = FakeSMTPServer(('127.0.0.1', 0), None)
|
cls.server = FakeSMTPServer(('127.0.0.1', 0), None)
|
||||||
cls._settings_override = override_settings(
|
cls._settings_override = override_settings(
|
||||||
EMAIL_HOST="127.0.0.1",
|
EMAIL_HOST="127.0.0.1",
|
||||||
|
@ -866,6 +867,7 @@ class SMTPBackendTests(BaseEmailBackendTests, SimpleTestCase):
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
cls._settings_override.disable()
|
cls._settings_override.disable()
|
||||||
cls.server.stop()
|
cls.server.stop()
|
||||||
|
super(SMTPBackendTests, cls).tearDownClass()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(SMTPBackendTests, self).setUp()
|
super(SMTPBackendTests, self).setUp()
|
||||||
|
|
|
@ -27,7 +27,7 @@ TEST_SETTINGS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='servers.urls')
|
@override_settings(ROOT_URLCONF='servers.urls', **TEST_SETTINGS)
|
||||||
class LiveServerBase(LiveServerTestCase):
|
class LiveServerBase(LiveServerTestCase):
|
||||||
|
|
||||||
available_apps = [
|
available_apps = [
|
||||||
|
@ -38,19 +38,6 @@ class LiveServerBase(LiveServerTestCase):
|
||||||
]
|
]
|
||||||
fixtures = ['testdata.json']
|
fixtures = ['testdata.json']
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
# Override settings
|
|
||||||
cls.settings_override = override_settings(**TEST_SETTINGS)
|
|
||||||
cls.settings_override.enable()
|
|
||||||
super(LiveServerBase, cls).setUpClass()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def tearDownClass(cls):
|
|
||||||
# Restore original settings
|
|
||||||
cls.settings_override.disable()
|
|
||||||
super(LiveServerBase, cls).tearDownClass()
|
|
||||||
|
|
||||||
def urlopen(self, url):
|
def urlopen(self, url):
|
||||||
return urlopen(self.live_server_url + url)
|
return urlopen(self.live_server_url + url)
|
||||||
|
|
||||||
|
|
|
@ -106,9 +106,19 @@ class ClassDecoratedTestCaseSuper(TestCase):
|
||||||
|
|
||||||
@override_settings(TEST='override')
|
@override_settings(TEST='override')
|
||||||
class ClassDecoratedTestCase(ClassDecoratedTestCaseSuper):
|
class ClassDecoratedTestCase(ClassDecoratedTestCaseSuper):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super(cls, ClassDecoratedTestCase).setUpClass()
|
||||||
|
cls.foo = getattr(settings, 'TEST', 'BUG')
|
||||||
|
|
||||||
def test_override(self):
|
def test_override(self):
|
||||||
self.assertEqual(settings.TEST, 'override')
|
self.assertEqual(settings.TEST, 'override')
|
||||||
|
|
||||||
|
def test_setupclass_override(self):
|
||||||
|
"""Test that settings are overriden within setUpClass -- refs #21281"""
|
||||||
|
self.assertEqual(self.foo, 'override')
|
||||||
|
|
||||||
@override_settings(TEST='override2')
|
@override_settings(TEST='override2')
|
||||||
def test_method_override(self):
|
def test_method_override(self):
|
||||||
self.assertEqual(settings.TEST, 'override2')
|
self.assertEqual(settings.TEST, 'override2')
|
||||||
|
|
|
@ -20,6 +20,7 @@ class TzinfoTests(IgnoreDeprecationWarningsMixin, unittest.TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
super(TzinfoTests, cls).setUpClass()
|
||||||
cls.old_TZ = os.environ.get('TZ')
|
cls.old_TZ = os.environ.get('TZ')
|
||||||
os.environ['TZ'] = 'US/Eastern'
|
os.environ['TZ'] = 'US/Eastern'
|
||||||
|
|
||||||
|
@ -41,6 +42,7 @@ class TzinfoTests(IgnoreDeprecationWarningsMixin, unittest.TestCase):
|
||||||
# Cleanup - force re-evaluation of TZ environment variable.
|
# Cleanup - force re-evaluation of TZ environment variable.
|
||||||
if cls.tz_tests:
|
if cls.tz_tests:
|
||||||
time.tzset()
|
time.tzset()
|
||||||
|
super(TzinfoTests, cls).tearDownClass()
|
||||||
|
|
||||||
def test_fixedoffset(self):
|
def test_fixedoffset(self):
|
||||||
self.assertEqual(repr(FixedOffset(0)), '+0000')
|
self.assertEqual(repr(FixedOffset(0)), '+0000')
|
||||||
|
|
Loading…
Reference in New Issue