Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No deprecation warnings while running unittests

When running unittests I would like to see deprecation warnings. It appears that since Python 2.7 deprecation warnings are silenced. I'll quote from the page:

For Python 2.7, a policy decision was made to silence warnings only of interest to developers by default. DeprecationWarning and its descendants are now ignored unless otherwise requested, preventing users from seeing warnings triggered by an application. This change was also made in the branch that became Python 3.2. (Discussed on stdlib-sig and carried out in issue 7319.)

Later it appears as though I should see deprecation warnings while running unittests:

The unittest module also automatically reenables deprecation warnings when running tests.

Well.. simply put, it doesn't work for me, so I must be doing something wrong. I've tested with the following code:

import warnings
import unittest

def spam():
    warnings.warn('test', DeprecationWarning, stacklevel=2)
    return 'spam'

class Eggs(object):
    def __init__(self):
        self.spam = spam()

class Test(unittest.TestCase):
    def test_warn(self):
        eggs = Eggs()
        self.assertEqual('spam', eggs.spam)

Then I run the code (saved in spam.py):

python -m 'unittest' spam

And this gives me the following output:

.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

No deprecation warning. So the question is; what am I doing wrong here?

like image 695
siebz0r Avatar asked Dec 16 '25 18:12

siebz0r


2 Answers

It looks like the documentation is wrong - in 2.7 unittest does not reenable deprecation warnings.

>>> import warnings
>>> from pprint import pprint

>>> pprint(warnings.filters)
[('ignore', None, <type 'exceptions.DeprecationWarning'>, None, 0),
 ('ignore', None, <type 'exceptions.PendingDeprecationWarning'>, None, 0),
 ('ignore', None, <type 'exceptions.ImportWarning'>, None, 0),
 ('ignore', None, <type 'exceptions.BytesWarning'>, None, 0)]

>>> import unittest
>>> pprint(warnings.filters)
[('ignore', None, <type 'exceptions.DeprecationWarning'>, None, 0),
 ('ignore', None, <type 'exceptions.PendingDeprecationWarning'>, None, 0),
 ('ignore', None, <type 'exceptions.ImportWarning'>, None, 0),
 ('ignore', None, <type 'exceptions.BytesWarning'>, None, 0)]

... and there is nothing in unittest.py that I saw which reenables DeprecationWarning.

You can of course enable them yourself:

warnings.simplefilter('always', DeprecationWarning)

Or on the command line:

$ python -Wd -m 'unittest' spam
spam.py:10: DeprecationWarning: test
  self.spam = spam()
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Or with a decorator applied to each of your unittest.TestCase functions so that DeprecationWarning is enabled only for testing:

import warnings
import unittest

def enable_DeprecationWarning(fn):
    def _wrapped(*args, **kwargs):
        with warnings.catch_warnings():
            warnings.simplefilter('always', DeprecationWarning)
            return fn(*args, **kwargs)
    return _wrapped

def spam():
    warnings.warn('test', DeprecationWarning, stacklevel=2)
    return 'spam'

class Eggs(object):
    def __init__(self):
        self.spam = spam()

class Test(unittest.TestCase):
    @enable_DeprecationWarning
    def test_warn(self):
        eggs = Eggs()
        self.assertEqual('spam', eggs.spam)

if __name__ == '__main__':
        unittest.main()

The command line option is probably the best for unit testing as it requires no code changes.

like image 111
mhawke Avatar answered Dec 19 '25 08:12

mhawke


Since I use Eclipse for Python development I decided to use a different solution than suggested. It is also possible to enable warnings using an environment variable. If the environment variable PYTHONWARNINGS is set to default deprecation warnings are shown.

In Eclipse (PyDev) the interpreter can be modified to include the environment variable. This way it is only enabled for projects using that interpreter.

pydev interpreter config

like image 42
siebz0r Avatar answered Dec 19 '25 08:12

siebz0r



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!