如果我看到记录在记录器上的任何警告,我希望我的Python unittest
测试失败。如何捕获记录器消息并使测试失败?
答案 0 :(得分:1)
unittest
具有assertLogs
上下文管理器,用于捕获日志记录(自Python 3.4开始添加,对于较旧的版本,使用unittest2
backport lib)。用法示例:
spam.py
(要测试的代码)
import logging
logging.getLogger(__name__).addHandler(logging.NullHandler())
def eggs():
logging.warning('hello world')
测试:
import unittest
import spam
class SpamTests(unittest.TestCase):
def test_eggs(self):
with self.assertLogs() as ctx:
spam.eggs()
# we expect one record to be captured
self.assertEqual(len(ctx.records), 1)
record = ctx.records[0]
# we expect the captured record to have the message 'hello world'
self.assertEqual(record.message, 'hello world')
如果您想对任何具有警告级别的记录进行测试失败,则可以例如检查捕获的记录,按级别过滤:
self.assertFalse([r for r in ctx.records if r.levelno == logging.WARNING])
答案 1 :(得分:0)
对于真正的单元测试,您实际上将要模拟对logger.war的调用,使用patch发出警告。然后,您可以使用该模拟程序来断言该函数是通过使用以下方法的补丁来调用,使用某些参数调用还是根本没有调用:assert_drawn_once(),assert_call_once_with()和assert_not_drawn()。 Patching很棒!
from unittest import TestCase
from unittest.mock import patch
from logging import warning
def simple_function(value):
if value == 5:
pass
else:
warning(msg='msg')
class TestSimpleFunction(TestCase):
@patch('test_stack_overflow.warning')
def test_simple_function_wrong_value(self, log_warning_call):
simple_function('5')
log_warning_call.assert_called_once()
log_warning_call.assert_called_once_with(msg='msg')
@patch('test_stack_overflow.warning')
def test_simple_function_right_value(self, log_warning_call):
simple_function(5)
log_warning_call.assert_not_called()
答案 2 :(得分:0)
什么都没记录,self.assertLogs()
contextManager发出一个AssertionError: no logs of level WARNING or higher triggered on root
。
我们正好相反。
这是我为避免这种情况写的摘录:
import logging
from contextlib import contextmanager
@contextmanager
def assertNoLog(self, level='WARNING'):
with self.assertLogs(level=level) as cm:
yield
logging.error("gotcha ! with 1 log, you cannot fail before I check ;p")
if cm.output[:-1]: # let's remove this last log
for r in cm.records[:-1]:
print(r) # print full failing logs for debug
raise AssertionError("Log with level >= {level} received".format(level=level),
cm.output[:-1])
以及在单元测试中:
def test_my_program(self):
with assert_no_log(self):
logging.warning('Oh no! an Unexpected warning! This should fail tests!')
返回:
AssertionError: ('Log with level >= WARNING received',
['WARNING:my.module:Oh no! an Unexpected warning! This should fail tests!'])