Merge pull request #3117 from boxed/access_logs_in_teardown

Access captures logs in teardown
This commit is contained in:
Bruno Oliveira 2018-01-20 11:21:17 -02:00 committed by GitHub
commit 3b3d237f07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 0 deletions

View File

@ -9,6 +9,7 @@ Ahn Ki-Wook
Alexander Johnson Alexander Johnson
Alexei Kozlenok Alexei Kozlenok
Anatoly Bubenkoff Anatoly Bubenkoff
Anders Hovmöller
Andras Tim Andras Tim
Andreas Zeidler Andreas Zeidler
Andrzej Ostrowski Andrzej Ostrowski

View File

@ -128,6 +128,13 @@ class LogCaptureFixture(object):
def handler(self): def handler(self):
return self._item.catch_log_handler return self._item.catch_log_handler
def get_handler(self, when):
"""
Get the handler for a specified state of the tests.
Valid values for the when parameter are: 'setup', 'call' and 'teardown'.
"""
return self._item.catch_log_handlers.get(when)
@property @property
def text(self): def text(self):
"""Returns the log text.""" """Returns the log text."""
@ -287,11 +294,16 @@ class LoggingPlugin(object):
"""Implements the internals of pytest_runtest_xxx() hook.""" """Implements the internals of pytest_runtest_xxx() hook."""
with catching_logs(LogCaptureHandler(), with catching_logs(LogCaptureHandler(),
formatter=self.formatter) as log_handler: formatter=self.formatter) as log_handler:
if not hasattr(item, 'catch_log_handlers'):
item.catch_log_handlers = {}
item.catch_log_handlers[when] = log_handler
item.catch_log_handler = log_handler item.catch_log_handler = log_handler
try: try:
yield # run test yield # run test
finally: finally:
del item.catch_log_handler del item.catch_log_handler
if when == 'teardown':
del item.catch_log_handlers
if self.print_logs: if self.print_logs:
# Add a captured log section to the report. # Add a captured log section to the report.

1
changelog/3117.feature Normal file
View File

@ -0,0 +1 @@
New ``caplog.get_handler(when)`` method which provides access to the underlying ``Handler`` class used to capture logging during each testing stage, allowing users to obtain the captured records during ``"setup"`` and ``"teardown"`` stages.

View File

@ -190,3 +190,12 @@ option names are:
* ``log_file_level`` * ``log_file_level``
* ``log_file_format`` * ``log_file_format``
* ``log_file_date_format`` * ``log_file_date_format``
Accessing logs from other test stages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``caplop.records`` fixture contains records from the current stage only. So
inside the setup phase it contains only setup logs, same with the call and
teardown phases. To access logs from other stages you can use
``caplog.get_handler('setup').records``. Valid stages are ``setup``, ``call``
and ``teardown``.

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging import logging
import pytest
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
sublogger = logging.getLogger(__name__ + '.baz') sublogger = logging.getLogger(__name__ + '.baz')
@ -68,3 +69,23 @@ def test_clear(caplog):
assert len(caplog.records) assert len(caplog.records)
caplog.clear() caplog.clear()
assert not len(caplog.records) assert not len(caplog.records)
@pytest.fixture
def logging_during_setup_and_teardown(caplog):
logger.info('a_setup_log')
yield
logger.info('a_teardown_log')
assert [x.message for x in caplog.get_handler('teardown').records] == ['a_teardown_log']
def test_caplog_captures_for_all_stages(caplog, logging_during_setup_and_teardown):
assert not caplog.records
assert not caplog.get_handler('call').records
logger.info('a_call_log')
assert [x.message for x in caplog.get_handler('call').records] == ['a_call_log']
assert [x.message for x in caplog.get_handler('setup').records] == ['a_setup_log']
# This reachers into private API, don't use this type of thing in real tests!
assert set(caplog._item.catch_log_handlers.keys()) == {'setup', 'call'}