Fixed #14508 - test suite silences warnings.
Utility functions get_warnings_state and save_warnings_state have been added to django.test.utils, and methods to django.test.TestCase for convenience. The implementation is based on the catch_warnings context manager from Python 2.6. git-svn-id: http://code.djangoproject.com/svn/django/trunk@14526 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
7beca4d3e5
commit
02fc6276d7
|
@ -154,13 +154,13 @@ class RowlevelBackendTest(TestCase):
|
||||||
self.user1 = User.objects.create_user('test', 'test@example.com', 'test')
|
self.user1 = User.objects.create_user('test', 'test@example.com', 'test')
|
||||||
self.user2 = User.objects.create_user('test2', 'test2@example.com', 'test')
|
self.user2 = User.objects.create_user('test2', 'test2@example.com', 'test')
|
||||||
self.user3 = User.objects.create_user('test3', 'test3@example.com', 'test')
|
self.user3 = User.objects.create_user('test3', 'test3@example.com', 'test')
|
||||||
|
self.save_warnings_state()
|
||||||
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
||||||
module='django.contrib.auth')
|
module='django.contrib.auth')
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
settings.AUTHENTICATION_BACKENDS = self.curr_auth
|
settings.AUTHENTICATION_BACKENDS = self.curr_auth
|
||||||
warnings.resetwarnings()
|
self.restore_warnings_state()
|
||||||
warnings.simplefilter('ignore', PendingDeprecationWarning)
|
|
||||||
|
|
||||||
def test_has_perm(self):
|
def test_has_perm(self):
|
||||||
self.assertEqual(self.user1.has_perm('perm', TestObj()), False)
|
self.assertEqual(self.user1.has_perm('perm', TestObj()), False)
|
||||||
|
|
|
@ -51,6 +51,7 @@ class BaseTest(TestCase):
|
||||||
self._message_storage = settings.MESSAGE_STORAGE
|
self._message_storage = settings.MESSAGE_STORAGE
|
||||||
settings.MESSAGE_STORAGE = '%s.%s' % (self.storage_class.__module__,
|
settings.MESSAGE_STORAGE = '%s.%s' % (self.storage_class.__module__,
|
||||||
self.storage_class.__name__)
|
self.storage_class.__name__)
|
||||||
|
self.save_warnings_state()
|
||||||
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
||||||
module='django.contrib.auth.models')
|
module='django.contrib.auth.models')
|
||||||
|
|
||||||
|
@ -63,8 +64,7 @@ class BaseTest(TestCase):
|
||||||
self._template_context_processors
|
self._template_context_processors
|
||||||
settings.INSTALLED_APPS = self._installed_apps
|
settings.INSTALLED_APPS = self._installed_apps
|
||||||
settings.MESSAGE_STORAGE = self._message_storage
|
settings.MESSAGE_STORAGE = self._message_storage
|
||||||
warnings.resetwarnings()
|
self.restore_warnings_state()
|
||||||
warnings.simplefilter('ignore', PendingDeprecationWarning)
|
|
||||||
|
|
||||||
def restore_setting(self, setting):
|
def restore_setting(self, setting):
|
||||||
if setting in self._remembered_settings:
|
if setting in self._remembered_settings:
|
||||||
|
|
|
@ -11,6 +11,7 @@ from django.db import transaction, connection, connections, DEFAULT_DB_ALIAS
|
||||||
from django.http import QueryDict
|
from django.http import QueryDict
|
||||||
from django.test import _doctest as doctest
|
from django.test import _doctest as doctest
|
||||||
from django.test.client import Client
|
from django.test.client import Client
|
||||||
|
from django.test.utils import get_warnings_state, restore_warnings_state
|
||||||
from django.utils import simplejson, unittest as ut2
|
from django.utils import simplejson, unittest as ut2
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
from django.utils.functional import wraps
|
from django.utils.functional import wraps
|
||||||
|
@ -328,6 +329,19 @@ class TransactionTestCase(ut2.TestCase):
|
||||||
settings.ROOT_URLCONF = self._old_root_urlconf
|
settings.ROOT_URLCONF = self._old_root_urlconf
|
||||||
clear_url_caches()
|
clear_url_caches()
|
||||||
|
|
||||||
|
def save_warnings_state(self):
|
||||||
|
"""
|
||||||
|
Saves the state of the warnings module
|
||||||
|
"""
|
||||||
|
self._warnings_state = get_warnings_state()
|
||||||
|
|
||||||
|
def restore_warnings_state(self):
|
||||||
|
"""
|
||||||
|
Restores the sate of the warnings module to the state
|
||||||
|
saved by save_warnings_state()
|
||||||
|
"""
|
||||||
|
restore_warnings_state(self._warnings_state)
|
||||||
|
|
||||||
def assertRedirects(self, response, expected_url, status_code=302,
|
def assertRedirects(self, response, expected_url, status_code=302,
|
||||||
target_status_code=200, host=None, msg_prefix=''):
|
target_status_code=200, host=None, msg_prefix=''):
|
||||||
"""Asserts that a response redirected to a specific URL, and that the
|
"""Asserts that a response redirected to a specific URL, and that the
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
|
import warnings
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.mail.backends import locmem
|
from django.core.mail.backends import locmem
|
||||||
|
@ -46,6 +47,7 @@ class ContextList(list):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def instrumented_test_render(self, context):
|
def instrumented_test_render(self, context):
|
||||||
"""
|
"""
|
||||||
An instrumented Template render method, providing a signal
|
An instrumented Template render method, providing a signal
|
||||||
|
@ -75,6 +77,7 @@ def setup_test_environment():
|
||||||
|
|
||||||
deactivate()
|
deactivate()
|
||||||
|
|
||||||
|
|
||||||
def teardown_test_environment():
|
def teardown_test_environment():
|
||||||
"""Perform any global post-test teardown. This involves:
|
"""Perform any global post-test teardown. This involves:
|
||||||
|
|
||||||
|
@ -93,6 +96,25 @@ def teardown_test_environment():
|
||||||
|
|
||||||
del mail.outbox
|
del mail.outbox
|
||||||
|
|
||||||
|
|
||||||
|
def get_warnings_state():
|
||||||
|
"""
|
||||||
|
Returns an object containing the state of the warnings module
|
||||||
|
"""
|
||||||
|
# There is no public interface for doing this, but this implementation of
|
||||||
|
# get_warnings_state and restore_warnings_state appears to work on Python
|
||||||
|
# 2.4 to 2.7.
|
||||||
|
return warnings.filters[:]
|
||||||
|
|
||||||
|
|
||||||
|
def restore_warnings_state(state):
|
||||||
|
"""
|
||||||
|
Restores the state of the warnings module when passed an object that was
|
||||||
|
returned by get_warnings_state()
|
||||||
|
"""
|
||||||
|
warnings.filters = state[:]
|
||||||
|
|
||||||
|
|
||||||
def get_runner(settings):
|
def get_runner(settings):
|
||||||
test_path = settings.TEST_RUNNER.split('.')
|
test_path = settings.TEST_RUNNER.split('.')
|
||||||
# Allow for Python 2.5 relative paths
|
# Allow for Python 2.5 relative paths
|
||||||
|
|
|
@ -15,6 +15,7 @@ from django.core.cache import get_cache
|
||||||
from django.core.cache.backends.base import InvalidCacheBackendError, CacheKeyWarning
|
from django.core.cache.backends.base import InvalidCacheBackendError, CacheKeyWarning
|
||||||
from django.http import HttpResponse, HttpRequest
|
from django.http import HttpResponse, HttpRequest
|
||||||
from django.middleware.cache import FetchFromCacheMiddleware, UpdateCacheMiddleware
|
from django.middleware.cache import FetchFromCacheMiddleware, UpdateCacheMiddleware
|
||||||
|
from django.test.utils import get_warnings_state, restore_warnings_state
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
from django.utils import unittest
|
from django.utils import unittest
|
||||||
from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key
|
from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key
|
||||||
|
@ -379,21 +380,16 @@ class BaseCacheTests(object):
|
||||||
# manager to test this warning nicely. Since we can't do that
|
# manager to test this warning nicely. Since we can't do that
|
||||||
# yet, the cleanest option is to temporarily ask for
|
# yet, the cleanest option is to temporarily ask for
|
||||||
# CacheKeyWarning to be raised as an exception.
|
# CacheKeyWarning to be raised as an exception.
|
||||||
|
_warnings_state = get_warnings_state()
|
||||||
warnings.simplefilter("error", CacheKeyWarning)
|
warnings.simplefilter("error", CacheKeyWarning)
|
||||||
|
|
||||||
# memcached does not allow whitespace or control characters in keys
|
try:
|
||||||
self.assertRaises(CacheKeyWarning, self.cache.set, 'key with spaces', 'value')
|
# memcached does not allow whitespace or control characters in keys
|
||||||
# memcached limits key length to 250
|
self.assertRaises(CacheKeyWarning, self.cache.set, 'key with spaces', 'value')
|
||||||
self.assertRaises(CacheKeyWarning, self.cache.set, 'a' * 251, 'value')
|
# memcached limits key length to 250
|
||||||
|
self.assertRaises(CacheKeyWarning, self.cache.set, 'a' * 251, 'value')
|
||||||
# The warnings module has no public API for getting the
|
finally:
|
||||||
# current list of warning filters, so we can't save that off
|
restore_warnings_state(_warnings_state)
|
||||||
# and reset to the previous value, we have to globally reset
|
|
||||||
# it. The effect will be the same, as long as the Django test
|
|
||||||
# runner doesn't add any global warning filters (it currently
|
|
||||||
# does not).
|
|
||||||
warnings.resetwarnings()
|
|
||||||
warnings.simplefilter("ignore", PendingDeprecationWarning)
|
|
||||||
|
|
||||||
class DBCacheTests(unittest.TestCase, BaseCacheTests):
|
class DBCacheTests(unittest.TestCase, BaseCacheTests):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
|
@ -48,14 +48,14 @@ class AuthContextProcessorTests(TestCase):
|
||||||
fixtures = ['context-processors-users.xml']
|
fixtures = ['context-processors-users.xml']
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
self.save_warnings_state()
|
||||||
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
||||||
module='django.contrib.auth.models')
|
module='django.contrib.auth.models')
|
||||||
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
||||||
module='django.core.context_processors')
|
module='django.core.context_processors')
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
warnings.resetwarnings()
|
self.restore_warnings_state()
|
||||||
warnings.simplefilter('ignore', PendingDeprecationWarning)
|
|
||||||
|
|
||||||
def test_session_not_accessed(self):
|
def test_session_not_accessed(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -71,12 +71,12 @@ class CsrfMiddlewareTest(TestCase):
|
||||||
_secret_key_for_session_test= "test"
|
_secret_key_for_session_test= "test"
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
self.save_warnings_state()
|
||||||
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
||||||
module='django.middleware.csrf')
|
module='django.middleware.csrf')
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
warnings.resetwarnings()
|
self.restore_warnings_state()
|
||||||
warnings.simplefilter('ignore', PendingDeprecationWarning)
|
|
||||||
|
|
||||||
def _get_GET_no_csrf_cookie_request(self):
|
def _get_GET_no_csrf_cookie_request(self):
|
||||||
return TestingHttpRequest()
|
return TestingHttpRequest()
|
||||||
|
|
|
@ -315,14 +315,14 @@ class DeprecatedSyndicationFeedTest(FeedTestCase):
|
||||||
Tests for the deprecated API (feed() view and the feed_dict etc).
|
Tests for the deprecated API (feed() view and the feed_dict etc).
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
self.save_warnings_state()
|
||||||
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
||||||
module='django.contrib.syndication.feeds')
|
module='django.contrib.syndication.feeds')
|
||||||
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
||||||
module='django.contrib.syndication.views')
|
module='django.contrib.syndication.views')
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
warnings.resetwarnings()
|
self.restore_warnings_state()
|
||||||
warnings.simplefilter('ignore', PendingDeprecationWarning)
|
|
||||||
|
|
||||||
def test_empty_feed_dict(self):
|
def test_empty_feed_dict(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -20,6 +20,7 @@ from django.template import TemplateDoesNotExist, Context
|
||||||
from django.template.loaders.eggs import load_template_source as lts_egg
|
from django.template.loaders.eggs import load_template_source as lts_egg
|
||||||
from django.template.loaders.eggs import Loader as EggLoader
|
from django.template.loaders.eggs import Loader as EggLoader
|
||||||
from django.template import loader
|
from django.template import loader
|
||||||
|
from django.test.utils import get_warnings_state, restore_warnings_state
|
||||||
from django.utils import unittest
|
from django.utils import unittest
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,13 +69,13 @@ class DeprecatedEggLoaderTest(unittest.TestCase):
|
||||||
})
|
})
|
||||||
self._old_installed_apps = settings.INSTALLED_APPS
|
self._old_installed_apps = settings.INSTALLED_APPS
|
||||||
settings.INSTALLED_APPS = []
|
settings.INSTALLED_APPS = []
|
||||||
|
self._warnings_state = get_warnings_state()
|
||||||
warnings.filterwarnings("ignore", category=DeprecationWarning,
|
warnings.filterwarnings("ignore", category=DeprecationWarning,
|
||||||
module='django.template.loaders.eggs')
|
module='django.template.loaders.eggs')
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
settings.INSTALLED_APPS = self._old_installed_apps
|
settings.INSTALLED_APPS = self._old_installed_apps
|
||||||
warnings.resetwarnings()
|
restore_warnings_state(self._warnings_state)
|
||||||
warnings.simplefilter("ignore", PendingDeprecationWarning)
|
|
||||||
|
|
||||||
def test_existing(self):
|
def test_existing(self):
|
||||||
"A template can be loaded from an egg"
|
"A template can be loaded from an egg"
|
||||||
|
|
|
@ -26,6 +26,35 @@ class SkippingTestCase(TestCase):
|
||||||
self.assertRaises(ValueError, test_func)
|
self.assertRaises(ValueError, test_func)
|
||||||
|
|
||||||
|
|
||||||
|
class SaveRestoreWarningState(TestCase):
|
||||||
|
|
||||||
|
def test_save_restore_warnings_state(self):
|
||||||
|
"""
|
||||||
|
Ensure save_warnings_state/restore_warnings_state work correctly.
|
||||||
|
"""
|
||||||
|
# In reality this test could be satisfied by many broken implementations
|
||||||
|
# of save_warnings_state/restore_warnings_state (e.g. just
|
||||||
|
# warnings.resetwarnings()) , but it is difficult to test more.
|
||||||
|
import warnings
|
||||||
|
self.save_warnings_state()
|
||||||
|
|
||||||
|
class MyWarning(Warning):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Add a filter that causes an exception to be thrown, so we can catch it
|
||||||
|
warnings.simplefilter("error", MyWarning)
|
||||||
|
self.assertRaises(Warning, lambda: warnings.warn("warn", MyWarning))
|
||||||
|
|
||||||
|
# Now restore.
|
||||||
|
self.restore_warnings_state()
|
||||||
|
# After restoring, we shouldn't get an exception. But we don't want a
|
||||||
|
# warning printed either, so we have to silence the warning.
|
||||||
|
warnings.simplefilter("ignore", MyWarning)
|
||||||
|
warnings.warn("warn", MyWarning)
|
||||||
|
|
||||||
|
# Remove the filter we just added.
|
||||||
|
self.restore_warnings_state()
|
||||||
|
|
||||||
__test__ = {"API_TEST": r"""
|
__test__ = {"API_TEST": r"""
|
||||||
# Some checks of the doctest output normalizer.
|
# Some checks of the doctest output normalizer.
|
||||||
# Standard doctests do fairly
|
# Standard doctests do fairly
|
||||||
|
|
Loading…
Reference in New Issue