你怎么能在Python中编写一个单元测试来测试记录器的输出确实是你期望的格式(即通过调用logging.basicConfig()来设置)?我正在考虑使用自定义StreamHandler并使用're'库,但它看起来不像传递给StreamHandler.emit()的LogRecord可以给我输出的字符串。
答案 0 :(得分:6)
从文档(http://packages.python.org/testfixtures/logging.html):
为了帮助解决这个问题,TestFixtures允许您轻松捕获对Python日志记录框架的调用输出,并确保它们符合预期。根据您正在编写的测试类型,有三种不同的技术。
示例包含在文档中。缩短版本如下。
>>> import logging
>>> from testfixtures import LogCapture
>>> with LogCapture() as l:
... logger = logging.getLogger()
... logger.info('a message')
... logger.error('an error')
之后,您可以检查日志是否相等:
>>> l.check(
... ('root', 'INFO', 'a message'),
... ('root', 'ERROR', 'another error'),
... )
Traceback (most recent call last):
...
AssertionError: Sequence not as expected:
same:
(('root', 'INFO', 'a message'),)
first:
(('root', 'ERROR', 'another error'),)
second:
(('root', 'ERROR', 'an error'),)
与之前类似,但适用于特定功能:
from testfixtures import log_capture
@log_capture()
def test_function(l):
logger = logging.getLogger()
logger.info('a message')
logger.error('an error')
l.check(
('root', 'INFO', 'a message'),
('root', 'ERROR', 'an error'),
)
>>> from testfixtures import LogCapture
>>> l = LogCapture()
之后您还可以“检查”日志:
>>> l.check(('root', 'INFO', 'a message'))
<...>
编辑:要访问特定日志并以自定义方式对其进行分析,您只需迭代l.records
(其中l
只是LogCapture
的实例)并访问每个属性(例如。msg
包含发送给记录器的消息,levelname
包含级别的代号,还有很多其他属性。)
答案 1 :(得分:0)
如果只想使用标准库,此解决方案可能会有所帮助。它基于unittest
和mock
库。
例如,如果您有script.py
并具有以下内容。
logger = logging.getLogger(__name__)
def log_something():
logger.debug("something")
您可以为此编写一个测试。
import unittest
import mock
from script import log_something
@mock.patch("script.logger")
def test_function(mock_log):
log_something()
assertTrue(
"something" in mock_log.debug.call_args_list[0][0][0]
)
这是使用mock
库中的call_args_list。
最后解释[0][0][0]
:
call_args_list
是call
对象的列表,看起来像这样的[call("something")]
。因此,第一个[0]
返回第一个call
对象。
第二个[0]
返回call
对象的参数元组。看起来像这样("something",)
。
第三[0]
返回在我们的情况下给logger
的第一个参数。因此,最后一个字符串将仅为"something"
。