#14508 closed (fixed)
Test suite silences warnings
Reported by: | Luke Plant | Owned by: | nobody |
---|---|---|---|
Component: | Testing framework | Version: | 1.2 |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The documentation encourages use of python -Wall manage.py test
to find PendingDeprecationWarning
. However, Django's test suite in many places silences warnings (e.g. DeprecationWarning
), and then 'restores' the state of warning filters to something other than what it was originally. So, for example, if you do:
python -Wall manage.py test auth myapp
the warnings from myapp
will not be shown as they ought.
Also, many warnings that Django's test suite itself emits are silenced by the current way of handling warnings - such as all the PendingDeprecationWarning
s emitted by unittest2.failUnless
etc., and some from cgi, depending on which tests are run and in what order.
Two things need to be done:
- Correctly save and restore the original filters.
warnings.catch_warnings
from Python 2.5 and greater shows how to do this. - Use more specific filters so that only warnings generated by Django are silenced, not those generated by unittest2. This is slightly tricky, since we are bundling unittest2 in the Django namespace.
Change History (5)
comment:1 by , 14 years ago
comment:2 by , 14 years ago
I've got a cleanup of the test suite on my to-do list just before the RC -- a search and replace for 'failUnless'->'assertTrue', 'assertEquals'->'assertEqual' etc is easy to do, but if we do it right now, it makes backporting tests to 1.2 a pain, since the diffs become incompatible. If we do this just before we land 1.3, then we don't have backporting issues to 1.2, and when we're developing 1.4, the diffs will be minimal.
The current approach of "reset to no-pending-deprecation-warnings" only exists because we can't retrieve the current warning state out of the warnings module. catch_warnings helps here, except for the fact that we can't use it in Python 2.4. If anyone can propose a way to restore old warning state that is Python 2.4 compatible, I'm all in favor of using it.
I've tried (as best I can) to catch all the places that we need to reset warnings, but evidently I've missed some. Specific reports are welcome, they're not easy to find, because they depend on specfic combinations of test ordering.
comment:3 by , 14 years ago
Copying warnings.filters
and assigning back again seems to work on Python 2.4 -> 2.6:
_saved = warnings.filters[:] ... warnings.filters = _saved
This works fine in a script, but something strange seems to happen at the interactive prompt when I do this. In fact, even without this I get very strange behaviour - for example if I add an 'ignore' simplefilter, followed by an 'always' simplefilter, and then do a warning, I don't get the same results at the interactive prompt compared to a script - typing exactly the same thing. Very strange. I'm seeing that behaviour with Python 2.4 - 2.6.
comment:4 by , 14 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:5 by , 14 years ago
(In [14527]) [1.2.X] 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.
Backport of [14526] from trunk.
Correction - the test suite does seem to use specific enough filters for the things it silences. However, it often doesn't silence
PendingDeprecationWarnings
that it ought to anticipate, so running withpython -Wall
produces far too much output - it should only produce output for things that need to be fixed.Also, it is easy to avoid silencing the warnings from the bundled unittest2 if we use fully qualified module regexes for the things we are expecting to silence e.g.
django\.contrib\.auth\.models
rather thandjango\..*