单元测试和记录 |捕获发送到 StreamHandler(sys.stdout) 的日志

unittest & logging | capture logs sent to StreamHandler(sys.stdout)

我想捕获发送到 Stream 的日志。

MyCode.py 将日志传递到控制台:2021-09-29 15:06:11,382 - root - ERROR - Started。然而,captured.records return什么都没有。 (输出中的前两行)

来源


问题


MyCode.py:

import logging
import sys

logger = logging.getLogger()
streamHandler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)
logger.addHandler(streamHandler)
logger.error('Started')

main.py:

import unittest
from unittest import TestCase
import MyCode

class TestExample(TestCase):
    def test_logging(self):
        with self.assertLogs() as captured:
            print('captured.records: ', captured.records)
            self.assertEqual(len(captured.records), 1)
            self.assertTrue("Started" in captured.records[0].getMessage())

if __name__ == '__main__':
    unittest.main()

控制台:

2021-09-29 15:06:11,382 - root - ERROR - Started
captured.records:  []
F
======================================================================
FAIL: test_logging (__main__.TestExample)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "main.py", line 9, in test_logging
    self.assertEqual(len(captured.records), 1)
AssertionError: 0 != 1

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)
repl process died unexpectedly: exit status 1

如果还有什么我应该添加到 post 的,请告诉我。

assertLogs 上下文管理器仅捕获在其上下文中创建的日志消息。您的日志消息是在导入 MyCode 时创建的,这发生在创建日志断言上下文之前。

如果您将代码放在一个函数中,并且 运行 该函数在测试中,它应该可以工作。

MyCode.py:

import logging
import sys

def foo():
    logger = logging.getLogger()
    streamHandler = logging.StreamHandler(sys.stdout)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - (message)s')
    streamHandler.setFormatter(formatter)
    logger.addHandler(streamHandler)
    logger.error('Started')

main.py:

import unittest
from unittest import TestCase
import MyCode

class TestExample(TestCase):
    def test_logging(self):
        with self.assertLogs() as captured:
            MyCode.foo()
            print('captured.records: ', captured.records)
            self.assertEqual(len(captured.records), 1)
            self.assertTrue("Started" in captured.records[0].getMessage())

if __name__ == '__main__':
    unittest.main()