为Python记录器格式化输出编写单元测试

Gra*_*eme 7 python logging unit-testing

你怎么能用Python编写一个单元测试来测试记录器的输出确实是你期望的格式(即通过调用logging.basicConfig()来设置)?我正在考虑自定义StreamHandler并使用're'库,但它看起来不像传递给StreamHandler.emit()的LogRecord可以给我输出的字符串.

Tad*_*eck 6

从文档(http://packages.python.org/testfixtures/logging.html):

为了解决这个问题,TestFixtures允许您轻松捕获对Python日志框架的调用输出,并确保它们符合预期.根据您正在编写的测试类型,有三种不同的技术.

  1. 上下文管理器
  2. 装饰者
  3. 手动使用

这些示例包含在文档中.缩短版本如下.

上下文管理器

>>> import logging
>>> from testfixtures import LogCapture
>>> with LogCapture() as l:
...     logger = logging.getLogger()
...     logger.info('a message')
...     logger.error('an error')
Run Code Online (Sandbox Code Playgroud)

之后,您可以检查日志是否相等:

>>> 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'),)
Run Code Online (Sandbox Code Playgroud)

装饰者

与之前类似,但适用于特定功能:

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'),
        )
Run Code Online (Sandbox Code Playgroud)

手动使用

>>> from testfixtures import LogCapture
>>> l = LogCapture()
Run Code Online (Sandbox Code Playgroud)

之后你还可以"检查"日志:

>>> l.check(('root', 'INFO', 'a message'))
<...>
Run Code Online (Sandbox Code Playgroud)

编辑:要访问特定日志并以自定义方式分析它们,您可以迭代l.records(在哪里l只是LogCapture实例)并访问每个日志的一些属性(例如,msg包含发送到记录器的消息,levelname包含级别的代号,还有很多其他的属性).