【问题标题】:How to suppress ImportWarning in a python unittest script如何在 python unittest 脚本中抑制 ImportWarning
【发布时间】:2018-12-05 07:38:55
【问题描述】:

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

提前致谢。

【问题讨论】:

  • 警告似乎来自依赖 pandas 包的测试之一,该包依赖于一堆依赖项

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


【解决方案1】:

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

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

可能需要一些工作来隔离代码中导致警告或利用第三方软件导致警告的特定位置,但开发人员将更清楚地了解警告的原因,而这只会提高程序的整体可维护性。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,并使用 warnings.simplefilter() 语句启动我的单元测试脚本,如 Nels 所述,这对我不起作用。根据this source,这是因为:

    [...] 从 Python 3.2 开始,unittest 模块已更新为在运行测试时使用警告模块默认过滤器,并且[...] 在每次测试之前重置为默认过滤器 ,这意味着您可能认为通过在脚本开头使用 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()
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2012-10-30
        • 2020-11-18
        • 2020-10-08
        • 1970-01-01
        • 1970-01-01
        • 2013-04-18
        • 1970-01-01
        • 1970-01-01
        • 2013-03-18
        相关资源
        最近更新 更多