提问人:SchEma 提问时间:9/21/2023 最后编辑:SchEma 更新时间:9/22/2023 访问量:52
'unittest.TestCase“使全局”warnings.filterwarnings“过时
`unittest.TestCase` makes global `warnings.filterwarnings` obsolete
问:
我有一个模块,其中包含一些方法,这些方法确实会引发大量警告。 碰巧的是,警告是由外部模块引发的。在给定的上下文中,它们并不是真正有用,但它们的丰富性非常烦人。
为了抑制警告,我打算使用该方法。因为它们无处不在,所以我决定一劳永逸地抑制它们,即在模块级别,而不是由上下文管理器一次又一次地抑制它们。
不是很优雅,但它可以解决问题。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
只产生“有趣”的东西。
test.py:
from unittest import TestCase
import warnings
import do
class DoTest(TestCase):
def test_do(self):
with warnings.catch_warnings(record=True) as ws:
do.main()
self.assertTrue([ w for w in ws if 'interesting' in w.message.args ])
self.assertFalse([ w for w in ws if 'boring' in w.message.args ])
python -m unittest
测试失败,并显示以下堆栈跟踪:
File "../test.py", line 13, in test_do
self.assertFalse([ w for w in ws if 'boring' in w.message.args ])
AssertionError: [<warnings.WarningMessage object at 0x000001EE01A2D220>] is not false```
答:
0赞
Danila Ganchar
9/21/2023
#1
这里有 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
评论
0赞
SchEma
9/22/2023
谢谢!有趣的方法,但这抑制了所有警告,我实际上需要在单元测试期间提供有趣的东西(我已经在这方面编辑了原始问题)。此外,我希望有一个“一劳永逸”的解决方案,不愿意编辑所有受影响的测试文件。(请参阅我在主要;)中的赞美。
0赞
Danila Ganchar
9/22/2023
@SchEma JFYI:您不需要修改所有测试。您可以创建 1 个基本测试类并从中继承。或者在测试执行之前设置某个位置。mock
0赞
Danila Ganchar
9/22/2023
我见过类似的问题。也许我只是不明白。看起来人们正在尝试为 a 或包编写测试。你能解释一下你正在解决什么问题吗?logging
warning
0赞
SchEma
9/24/2023
是的,我可以创建自己的派生类来继承,但我仍然需要更新所有测试模块。我试图解决的问题是,我的单元测试的控制台输出非常大,以至于在包含任何人类可读的有用信息之前必须对其进行进一步处理。是的,当然,我正在测试应用程序的日志记录和警告。其中一些至关重要。TestCase
评论