Как подавить ImportWarning в скрипте юнит тестирования python - PullRequest
0 голосов
/ 26 июня 2018

В настоящее время я запускаю скрипт unittest, который успешно проходит различные указанные тесты с неприятным сообщением ImportWarning в консоли:

...../lib/python3.6/importlib/_bootstrap.py:219: ImportWarning: can't resolve package from __spec__ or __package__, falling back on __name__ and __path__
  return f(*args, **kwds)
....
----------------------------------------------------------------------
Ran 7 tests in 1.950s

OK

Сценарий запускается с этой основной функцией:

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

Я прочитал, что предупреждения могут подавляться, когда скрипт вызывается так:

python  -W ignore:ImportWarning -m unittest testscript.py

Однако есть ли способ указать это предупреждение об игнорировании в самом скрипте, чтобы мне не приходилось вызывать -W ignore:ImportWarning каждый раз, когда запускается тестовый скрипт?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

У меня была такая же проблема, и запуск моего скрипта unittest с оператором warnings.simplefilter(), как описано Nels, не работает для меня. Согласно этому источнику , это потому что:

[...] начиная с Python 3.2, модуль unittest был обновлен для использования фильтра по умолчанию для модуля предупреждений при запуске тестов, и [...] сбрасывается на фильтр по умолчанию перед каждым тестом , Это означает, что любое изменение, которое, по вашему мнению, вы вносите в сценарий, используя warnings.simplefilter («игнорировать») в начале сценария, переопределяется между каждым тестом.

Этот же источник рекомендует обновить фильтр внутри каждой тестовой функции, либо напрямую, либо с помощью элегантного декоратора. Более простое решение - определить фильтр предупреждений внутри метода unittest setUp(), который запускается непосредственно перед каждым тестом.

import unittest
class TestSomething(unittest.TestCase):
    def setUp(self):
        warnings.simplefilter('ignore', category=ImportWarning)
        # Other initialization stuff here

    def test_a(self):
        # Test assertion here.

if __name__ == '__main__':
    unittest.main()
0 голосов
/ 30 июля 2018

Чтобы программно предотвратить появление таких предупреждений, настройте код так, чтобы:

import warnings
if __name__ == '__main__':
    with warnings.catch_warnings():
        warnings.simplefilter('ignore', category=ImportWarning)
        unittest.main()

Источник: https://stackoverflow.com/a/40994600/328469

Обновление:

@ billjoie, безусловно, правильно. Если ОП решает сделать ответ 52463661 принятым ответом, я согласен с этим. Я могу подтвердить, что следующее эффективно для подавления таких предупреждающих сообщений во время выполнения, используя Python версий 2.7.11, 3.4.3, 3.5.4, 3.6.5 и 3.7.1:

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import unittest
import warnings


class TestPandasImport(unittest.TestCase):
    def setUp(self):
        warnings.simplefilter('ignore', category=ImportWarning)

    def test_01(self):
        import pandas  # noqa: E402
        self.assertTrue(True)

    def test_02(self):
        import pandas  # noqa: E402
        self.assertFalse(False)


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

Тем не менее, я думаю, что OP следует рассмотреть возможность более глубокого изучения целей кода приложения модульных тестов, и попытаться определить импорт или операцию конкретного пакета, вызывающего фактическое предупреждение, а затем подавить предупреждение как можно ближе насколько это возможно, к месту в коде, где нарушение имеет место. Это избавит от подавления предупреждений на протяжении всего класса юнит-тестирования, что может непреднамеренно скрывать предупреждения от других частей программы.

Вне модульного теста, где-то в коде приложения:

with warnings.catch_warnings():
    warnings.simplefilter('ignore', category=ImportWarning)
    # import pandas
    # or_ideally_the_application_code_unit_that_imports_pandas()

Может потребоваться небольшая работа, чтобы выделить конкретное место в коде, которое либо вызывает предупреждение, либо использует стороннее программное обеспечение, которое вызывает предупреждение, но разработчик получит более четкое понимание причины предупреждения, и это только улучшит общую ремонтопригодность программы.

...