我有一个模块,其中的一些方法确实会引发大量警告。 碰巧的是,警告是由外部模块引发的。在给定的上下文中,它们并不是真正有用,但它们的丰富性却相当烦人。
为了抑制警告,我打算使用
warnings.filterwarnings
方法。因为它们无处不在,所以我决定一次性抑制它们,即在模块级别,而不是通过 catch_warnings
上下文管理器一次又一次地抑制它们。
不是很优雅,但它确实有效。
仅 - 它在
unittest.TestCase
中不起作用,这种抑制被简单地忽略。我发现在 TestCase
初始化和运行实际 test_method
之间的一段时间,在过滤器列表前面插入了几个过滤器,其中 ('default', None, <class 'Warning'>, None, 0)
,这使得后面的模块插入过滤器变得无用.
现在的问题是:如何绕过这个“功能”并抑制测试中的警告?
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
还渲染“无聊”的部分。
这里有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