如何在python unittest脚本中禁止ImportWarning

时间:2018-06-26 14:26:40

标签: python-3.x python-import python-unittest

我当前正在运行一个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

谢谢。

3 个答案:

答案 0 :(得分:5)

要以编程方式阻止此类警告的出现,请调整代码,以便:

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

来源:https://stackoverflow.com/a/40994600/328469

更新

@billjoie当然是正确的。如果OP选择使answer 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()

要在代码中找出引起警告的特定位置,或者利用引起警告的第三方软件,需要花费一些工作,但是开发人员会更清楚地了解警告的原因,这只会提高程序的整体可维护性。

答案 1 :(得分:3)

我遇到了同样的问题,并且按照Nels的描述,使用warnings.simplefilter()语句启动我的unittest脚本,这对我不起作用。根据{{​​3}},这是因为:

  

[...]自Python 3.2起,已将unittest模块更新为在运行测试时使用警告模块默认过滤器,并且[strong]在每次测试前重置为默认过滤器 ,这意味着您可能认为通过在脚本开头使用warnings.simplefilter(“ ignore”)在脚本范围内进行的任何更改都会在每次测试之间被覆盖。

同一来源建议直接或使用优雅的装饰器更新每个测试功能内部的过滤器。一个更简单的解决方案是在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()

答案 2 :(得分:1)

在使用 unittest 时,我在 Pycharm 中对一项测试遇到了相同的警告。当我在测试期间停止尝试导入库时,此警告消失了(我将导入移到了它应该位于的顶部)。我知道该请求是为了抑制,但如果它仅在选定数量的测试中发生,这也会使其消失。