I want to capture logs that are sent to Stream.
MyCode.py
passes log to console: 2021-09-29 15:06:11,382 - root - ERROR - Started
. However, captured.records
returns nothing. (First 2 lines in output)
Sources
Questions
- Why does
captured
return nothing? - How can I capture logs sent to
StreamHandler(sys.stdout)
?
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()
Console:
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
Please let me know if there's anything else I should add to post.
CodePudding user response:
The assertLogs
context manager only captures log messages that are created in its context. Your log messages were created when MyCode
was imported, which happened before the log assertion context was created.
If you put your code in a function, and run that function within the test, it should work.
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()