Нет предупреждений об устаревании при запуске модульных тестов

При запуске unittests я хотел бы видеть предупреждения об устаревании. Похоже, что поскольку предупреждения об устаревании Python 2.7 отключены. Цитирую со страницы:

Для Python 2.7 было принято политическое решение по умолчанию отключать предупреждения, представляющие интерес только для разработчиков. DeprecationWarning и его потомки теперь игнорируются, если не запрашивается иное, что не позволяет пользователям видеть предупреждения, запускаемые приложением. Это изменение также было внесено в ветку, которая стала Python 3.2. (Обсуждается на stdlib-sig и выполняется в выпуске 7319.)

Позже кажется, что я должен видеть предупреждения об устаревании при запуске unittests:

Модуль unittest также автоматически повторно включает предупреждения об устаревании при запуске тестов.

Ну ... Попросту говоря, у меня это не работает, так что я, должно быть, делаю что-то не так. Я тестировал следующий код:

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)

Затем я запускаю код (сохраненный в spam.py):

python -m 'unittest' spam

И это дает мне следующий результат:

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

OK

Нет предупреждения об устаревании. Итак, вопрос: что я здесь делаю не так?


person siebz0r    schedule 26.08.2014    source источник


Ответы (2)


Похоже, что документация неверна - в 2.7 unittest не включает предупреждения об устаревании.

>>> 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)]

... и нет ничего в unittest.py, что я видел, что повторно включает DeprecationWarning.

Конечно, вы можете включить их самостоятельно:

warnings.simplefilter('always', DeprecationWarning)

Или в командной строке:

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

OK

Или с декоратором, примененным к каждой из ваших unittest.TestCase функций, чтобы DeprecationWarning был включен только для тестирования:

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()

Параметр командной строки, вероятно, лучше всего подходит для модульного тестирования, поскольку он не требует изменения кода.

person mhawke    schedule 26.08.2014
comment
unittest изменяет warnings фильтр во время выполнения, а не во время импорта. См. здесь. - person saaj; 16.09.2016
comment
@saaj: Так почему же тогда не появляются предупреждения? Этот вопрос относится к Python 2.7; похоже, вы ссылаетесь на исходный код Python 3.5. - person mhawke; 17.09.2016
comment
Ты прав. Я пропустил метку. Этот фрагмент кода работает должным образом в latest (3.5) и не работает в 2 (2.7). Вероятно, неверна только страница "Что нового". unittest документы для 2.7 не описывают, что что-то повторно включено, в то время как документы для 3 работают. - person saaj; 18.09.2016

Поскольку я использую Eclipse для разработки на Python, я решил использовать другое решение, чем было предложено. Также можно включить предупреждения с помощью переменной среды. Если для переменной среды PYTHONWARNINGS установлено значение default, отображаются предупреждения об устаревании.

В Eclipse (PyDev) интерпретатор можно изменить, включив в него переменную среды. Таким образом, он доступен только для проектов, использующих этот интерпретатор.

Конфигурация интерпретатора pydev

person siebz0r    schedule 27.08.2014