如何在python单元测试脚本中抑制ImportWarning

Mys*_*rio 8 python-import python-3.x python-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
Run Code Online (Sandbox Code Playgroud)

该脚本使用以下主函数运行:

if __name__ == '__main__':
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

我已经读过,当脚本被调用时,警告会被压抑:

python  -W ignore:ImportWarning -m unittest testscript.py
Run Code Online (Sandbox Code Playgroud)

但是,有没有办法在脚本本身中指定此忽略警告,以便-W ignore:ImportWarning每次运行testscript时都不必调用?

提前致谢.

bil*_*oie 13

我遇到了同样的问题,并且warnings.simplefilter()按照 Nels 的描述,用一个语句启动我的单元测试脚本,这对我来说不起作用。根据这个消息来源, this is because:

\n\n
\n

[...] 从 Python 3.2 开始,unittest 模块已更新为在运行测试时使用警告模块默认过滤器,并且 [...]在每次测试之前重置为默认过滤器, meaning that any change you may think you are making scriptwide by using warnings.simplefilter(\xe2\x80\x9cignore\xe2\x80\x9d) at the beginning of your script gets overridden in between every test.

\n
\n\n

该消息来源建议直接或使用优雅的装饰器更新每个测试函数内部的过滤器。一个更简单的解决方案是在 unittest 中定义警告过滤器setUp() method, which is run right before each test.

\n\n
import unittest\nclass TestSomething(unittest.TestCase):\n    def setUp(self):\n        warnings.simplefilter(\'ignore\', category=ImportWarning)\n        # Other initialization stuff here\n\n    def test_a(self):\n        # Test assertion here.\n\nif __name__ == \'__main__\':\n    unittest.main()\n
Run Code Online (Sandbox Code Playgroud)\n


Nel*_*els 6

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

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

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

更新:

@billjoie当然是正确的。如果OP选择将答案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()
Run Code Online (Sandbox Code Playgroud)

但是,我认为OP应该考虑对单元测试的应用程序代码目标进行更深入的调查,并尝试识别导致实际警告的特定程序包导入或操作,然后尽可能地将警告抑制为代码中发生违规的位置。这将消除对整个单元测试类的警告的抑制,这可能会无意中使程序其他部分的警告变得晦涩。

在单元测试之外,在应用程序代码中的某个位置:

with warnings.catch_warnings():
    warnings.simplefilter('ignore', category=ImportWarning)
    # import pandas
    # or_ideally_the_application_code_unit_that_imports_pandas()
Run Code Online (Sandbox Code Playgroud)

可能需要一些工作来隔离代码中引起警告的特定点,或者利用引起警告的第三方软件,但是开发人员将更清楚地了解警告的原因,并且这将仅提高程序的整体可维护性。