mirror of
https://github.com/python/cpython.git
synced 2025-07-07 11:25:30 +00:00
gh-134567: Add the formatter parameter in unittest.TestCase.assertLogs (GH-134570)
This commit is contained in:
parent
b19c9da401
commit
51ab66b3d5
6 changed files with 42 additions and 5 deletions
|
@ -1131,7 +1131,7 @@ Test cases
|
|||
.. versionchanged:: 3.3
|
||||
Added the *msg* keyword argument when used as a context manager.
|
||||
|
||||
.. method:: assertLogs(logger=None, level=None)
|
||||
.. method:: assertLogs(logger=None, level=None, formatter=None)
|
||||
|
||||
A context manager to test that at least one message is logged on
|
||||
the *logger* or one of its children, with at least the given
|
||||
|
@ -1146,6 +1146,10 @@ Test cases
|
|||
its string equivalent (for example either ``"ERROR"`` or
|
||||
:const:`logging.ERROR`). The default is :const:`logging.INFO`.
|
||||
|
||||
If given, *formatter* should be a :class:`logging.Formatter` object.
|
||||
The default is a formatter with format string
|
||||
``"%(levelname)s:%(name)s:%(message)s"``
|
||||
|
||||
The test passes if at least one message emitted inside the ``with``
|
||||
block matches the *logger* and *level* conditions, otherwise it fails.
|
||||
|
||||
|
@ -1173,6 +1177,9 @@ Test cases
|
|||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
.. versionchanged:: next
|
||||
Now accepts a *formatter* to control how messages are formatted.
|
||||
|
||||
.. method:: assertNoLogs(logger=None, level=None)
|
||||
|
||||
A context manager to test that no messages are logged on
|
||||
|
|
|
@ -291,6 +291,15 @@ typing
|
|||
(Contributed by Bénédikt Tran in :gh:`133823`.)
|
||||
|
||||
|
||||
unittest
|
||||
--------
|
||||
|
||||
* Lets users specify formatter in TestCase.assertLogs.
|
||||
:func:`unittest.TestCase.assertLogs` will now accept a formatter
|
||||
to control how messages are formatted.
|
||||
(Contributed by Garry Cairns in :gh:`134567`.)
|
||||
|
||||
|
||||
wave
|
||||
----
|
||||
|
||||
|
|
|
@ -1920,6 +1920,22 @@ test case
|
|||
with self.assertLogs():
|
||||
raise ZeroDivisionError("Unexpected")
|
||||
|
||||
def testAssertLogsWithFormatter(self):
|
||||
# Check alternative formats will be respected
|
||||
format = "[No.1: the larch] %(levelname)s:%(name)s:%(message)s"
|
||||
formatter = logging.Formatter(format)
|
||||
with self.assertNoStderr():
|
||||
with self.assertLogs() as cm:
|
||||
log_foo.info("1")
|
||||
log_foobar.debug("2")
|
||||
self.assertEqual(cm.output, ["INFO:foo:1"])
|
||||
self.assertLogRecords(cm.records, [{'name': 'foo'}])
|
||||
with self.assertLogs(formatter=formatter) as cm:
|
||||
log_foo.info("1")
|
||||
log_foobar.debug("2")
|
||||
self.assertEqual(cm.output, ["[No.1: the larch] INFO:foo:1"])
|
||||
self.assertLogRecords(cm.records, [{'name': 'foo'}])
|
||||
|
||||
def testAssertNoLogsDefault(self):
|
||||
with self.assertRaises(self.failureException) as cm:
|
||||
with self.assertNoLogs():
|
||||
|
|
|
@ -30,7 +30,7 @@ class _AssertLogsContext(_BaseTestCaseContext):
|
|||
|
||||
LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s"
|
||||
|
||||
def __init__(self, test_case, logger_name, level, no_logs):
|
||||
def __init__(self, test_case, logger_name, level, no_logs, formatter=None):
|
||||
_BaseTestCaseContext.__init__(self, test_case)
|
||||
self.logger_name = logger_name
|
||||
if level:
|
||||
|
@ -39,13 +39,14 @@ class _AssertLogsContext(_BaseTestCaseContext):
|
|||
self.level = logging.INFO
|
||||
self.msg = None
|
||||
self.no_logs = no_logs
|
||||
self.formatter = formatter
|
||||
|
||||
def __enter__(self):
|
||||
if isinstance(self.logger_name, logging.Logger):
|
||||
logger = self.logger = self.logger_name
|
||||
else:
|
||||
logger = self.logger = logging.getLogger(self.logger_name)
|
||||
formatter = logging.Formatter(self.LOGGING_FORMAT)
|
||||
formatter = self.formatter or logging.Formatter(self.LOGGING_FORMAT)
|
||||
handler = _CapturingHandler()
|
||||
handler.setLevel(self.level)
|
||||
handler.setFormatter(formatter)
|
||||
|
|
|
@ -849,7 +849,7 @@ class TestCase(object):
|
|||
context = _AssertNotWarnsContext(expected_warning, self)
|
||||
return context.handle('_assertNotWarns', args, kwargs)
|
||||
|
||||
def assertLogs(self, logger=None, level=None):
|
||||
def assertLogs(self, logger=None, level=None, formatter=None):
|
||||
"""Fail unless a log message of level *level* or higher is emitted
|
||||
on *logger_name* or its children. If omitted, *level* defaults to
|
||||
INFO and *logger* defaults to the root logger.
|
||||
|
@ -861,6 +861,8 @@ class TestCase(object):
|
|||
`records` attribute will be a list of the corresponding LogRecord
|
||||
objects.
|
||||
|
||||
Optionally supply `formatter` to control how messages are formatted.
|
||||
|
||||
Example::
|
||||
|
||||
with self.assertLogs('foo', level='INFO') as cm:
|
||||
|
@ -871,7 +873,7 @@ class TestCase(object):
|
|||
"""
|
||||
# Lazy import to avoid importing logging if it is not needed.
|
||||
from ._log import _AssertLogsContext
|
||||
return _AssertLogsContext(self, logger, level, no_logs=False)
|
||||
return _AssertLogsContext(self, logger, level, no_logs=False, formatter=formatter)
|
||||
|
||||
def assertNoLogs(self, logger=None, level=None):
|
||||
""" Fail unless no log messages of level *level* or higher are emitted
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Expose log formatter to users in TestCase.assertLogs.
|
||||
:func:`unittest.TestCase.assertLogs` will now optionally accept a formatter that will be used to format the strings in output if provided.
|
Loading…
Add table
Add a link
Reference in a new issue