`unittest.TestCase` 使全局 `warnings.filterwarnings` 过时

问题描述 投票:0回答:1

我有一个模块,其中的一些方法确实会引发大量警告。 碰巧的是,警告是由外部模块引发的。在给定的上下文中,它们并不是真正有用,但它们的丰富性却相当烦人。

为了抑制警告,我打算使用

warnings.filterwarnings
方法。因为它们无处不在,所以我决定一次性抑制它们,即在模块级别,而不是通过
catch_warnings
上下文管理器一次又一次地抑制它们。 不是很优雅,但它确实有效。

仅 - 它在

unittest.TestCase
中不起作用,这种抑制被简单地忽略。我发现在
TestCase
初始化和运行实际
test_method
之间的一段时间,在过滤器列表前面插入了几个过滤器,其中
('default', None, <class 'Warning'>, None, 0)
,这使得后面的模块插入过滤器变得无用.

现在的问题是:如何绕过这个“功能”并抑制测试中的警告?

MRE

do.py:

import warnings

warnings.filterwarnings(
    action='ignore',
    message='boring',
)


def main():
    warnings.warn('boring')
    warnings.warn('interesting')


if __name__ == '__main__':
    main()

python do.py
只产生“有趣”的东西。

测试.py:

from unittest import TestCase

from do import main


class DoTest(TestCase):

    def test_do(self):
        main()

python -m unittest test
还渲染“无聊”的部分。

python warnings python-unittest
1个回答
0
投票

这里有2个例子:

from unittest import TestCase, mock
from unittest.mock import Mock

from do import main


# mock warnings for all class tests
class DoTest(TestCase):
    WARNING_MOCK = mock.patch('warnings.warn', return_value=Mock())

    @classmethod
    def setUpClass(cls) -> None:
        cls.WARNING_MOCK.start()  # disable warnings before tests

    @classmethod
    def tearDownClass(cls) -> None:
        cls.WARNING_MOCK.stop()  # enable warnings after tests

    def test_do(self):
        main()


# or using 'with' statement to call a context manager
# in this case you'll mock warnings only for specific test
class DoTest2(TestCase):
    def test_do(self):
        with mock.patch('warnings.warn', return_value=Mock()):
            main()

让我们检查一下

python -m unittest test

..
----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK
© www.soinside.com 2019 - 2024. All rights reserved.