Skip to content

Commit f8ff127

Browse files
committed
Exposes log format to users in unittest.TestCase.assertLogs
1 parent 366d95d commit f8ff127

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

Lib/test/test_unittest/test_case.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,6 +1920,22 @@ def testAssertLogsUnexpectedException(self):
19201920
with self.assertLogs():
19211921
raise ZeroDivisionError("Unexpected")
19221922

1923+
def testAssertLogsWithFormatter(self):
1924+
# Check alternative formats will be respected
1925+
format = "[No.1: the larch] %(levelname)s:%(name)s:%(message)s"
1926+
formatter = logging.Formatter(format)
1927+
with self.assertNoStderr():
1928+
with self.assertLogs() as cm:
1929+
log_foo.info("1")
1930+
log_foobar.debug("2")
1931+
self.assertEqual(cm.output, ["INFO:foo:1"])
1932+
self.assertLogRecords(cm.records, [{'name': 'foo'}])
1933+
with self.assertLogs(formatter=formatter) as cm:
1934+
log_foo.info("1")
1935+
log_foobar.debug("2")
1936+
self.assertEqual(cm.output, ["[No.1: the larch] INFO:foo:1"])
1937+
self.assertLogRecords(cm.records, [{'name': 'foo'}])
1938+
19231939
def testAssertNoLogsDefault(self):
19241940
with self.assertRaises(self.failureException) as cm:
19251941
with self.assertNoLogs():

Lib/unittest/_log.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class _AssertLogsContext(_BaseTestCaseContext):
3030

3131
LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s"
3232

33-
def __init__(self, test_case, logger_name, level, no_logs):
33+
def __init__(self, test_case, logger_name, level, no_logs, formatter=None):
3434
_BaseTestCaseContext.__init__(self, test_case)
3535
self.logger_name = logger_name
3636
if level:
@@ -39,13 +39,14 @@ def __init__(self, test_case, logger_name, level, no_logs):
3939
self.level = logging.INFO
4040
self.msg = None
4141
self.no_logs = no_logs
42+
self.formatter = formatter
4243

4344
def __enter__(self):
4445
if isinstance(self.logger_name, logging.Logger):
4546
logger = self.logger = self.logger_name
4647
else:
4748
logger = self.logger = logging.getLogger(self.logger_name)
48-
formatter = logging.Formatter(self.LOGGING_FORMAT)
49+
formatter = self.formatter or logging.Formatter(self.LOGGING_FORMAT)
4950
handler = _CapturingHandler()
5051
handler.setLevel(self.level)
5152
handler.setFormatter(formatter)

Lib/unittest/case.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ def _assertNotWarns(self, expected_warning, *args, **kwargs):
851851
context = _AssertNotWarnsContext(expected_warning, self)
852852
return context.handle('_assertNotWarns', args, kwargs)
853853

854-
def assertLogs(self, logger=None, level=None):
854+
def assertLogs(self, logger=None, level=None, formatter=None):
855855
"""Fail unless a log message of level *level* or higher is emitted
856856
on *logger_name* or its children. If omitted, *level* defaults to
857857
INFO and *logger* defaults to the root logger.
@@ -863,6 +863,8 @@ def assertLogs(self, logger=None, level=None):
863863
`records` attribute will be a list of the corresponding LogRecord
864864
objects.
865865
866+
Optionally supply `format` to control how messages are formatted.
867+
866868
Example::
867869
868870
with self.assertLogs('foo', level='INFO') as cm:
@@ -873,7 +875,7 @@ def assertLogs(self, logger=None, level=None):
873875
"""
874876
# Lazy import to avoid importing logging if it is not needed.
875877
from ._log import _AssertLogsContext
876-
return _AssertLogsContext(self, logger, level, no_logs=False)
878+
return _AssertLogsContext(self, logger, level, no_logs=False, formatter=formatter)
877879

878880
def assertNoLogs(self, logger=None, level=None):
879881
""" Fail unless no log messages of level *level* or higher are emitted

0 commit comments

Comments
 (0)