Live log option now writes to the terminal reporter

Ref: #3013
This commit is contained in:
Bruno Oliveira 2018-01-16 20:47:27 -02:00
parent aca1b06747
commit 8d735f3e1d
2 changed files with 44 additions and 33 deletions

View File

@ -2,7 +2,6 @@ from __future__ import absolute_import, division, print_function
import logging
from contextlib import closing, contextmanager
import sys
import six
import pytest
@ -270,30 +269,13 @@ class LoggingPlugin(object):
The formatter can be safely shared across all handlers so
create a single one for the entire test session here.
"""
self._config = config
self.print_logs = get_option_ini(config, 'log_print')
self.formatter = logging.Formatter(
get_option_ini(config, 'log_format'),
get_option_ini(config, 'log_date_format'))
self.log_level = get_actual_log_level(config, 'log_level')
if config.getini('log_cli'):
log_cli_handler = logging.StreamHandler(sys.stderr)
log_cli_format = get_option_ini(
config, 'log_cli_format', 'log_format')
log_cli_date_format = get_option_ini(
config, 'log_cli_date_format', 'log_date_format')
log_cli_formatter = logging.Formatter(
log_cli_format,
datefmt=log_cli_date_format)
log_cli_level = get_actual_log_level(config, 'log_cli_level', 'log_level')
self.log_cli_handler = log_cli_handler # needed for a single unittest
self.live_logs_context = catching_logs(log_cli_handler,
formatter=log_cli_formatter,
level=log_cli_level)
else:
self.log_cli_handler = None
self.live_logs_context = _dummy_context_manager()
log_file = get_option_ini(config, 'log_file')
if log_file:
self.log_file_level = get_actual_log_level(config, 'log_file_level')
@ -352,6 +334,7 @@ class LoggingPlugin(object):
@pytest.hookimpl(hookwrapper=True)
def pytest_runtestloop(self, session):
"""Runs all collected test items."""
self._setup_cli_logging()
with self.live_logs_context:
if self.log_file_handler is not None:
with closing(self.log_file_handler):
@ -360,3 +343,27 @@ class LoggingPlugin(object):
yield # run all the tests
else:
yield # run all the tests
def _setup_cli_logging(self):
"""Setups the handler and logger for the Live Logs feature, if enabled.
This must be done right before starting the loop so we can access the terminal reporter plugin.
"""
terminal_reporter = self._config.pluginmanager.get_plugin('terminalreporter')
if self._config.getini('log_cli') and terminal_reporter is not None:
log_cli_handler = logging.StreamHandler(terminal_reporter._tw)
log_cli_format = get_option_ini(
self._config, 'log_cli_format', 'log_format')
log_cli_date_format = get_option_ini(
self._config, 'log_cli_date_format', 'log_date_format')
log_cli_formatter = logging.Formatter(
log_cli_format,
datefmt=log_cli_date_format)
log_cli_level = get_actual_log_level(self._config, 'log_cli_level', 'log_level')
self.log_cli_handler = log_cli_handler # needed for a single unittest
self.live_logs_context = catching_logs(log_cli_handler,
formatter=log_cli_formatter,
level=log_cli_level)
else:
self.log_cli_handler = None
self.live_logs_context = _dummy_context_manager()

View File

@ -156,9 +156,9 @@ def test_log_cli_enabled_disabled(testdir, enabled):
''')
result = testdir.runpytest('-s')
if enabled:
assert msg in result.stderr.str()
assert msg in result.stdout.str()
else:
assert msg not in result.stderr.str()
assert msg not in result.stdout.str()
def test_log_cli_default_level(testdir):
@ -182,12 +182,13 @@ def test_log_cli_default_level(testdir):
# fnmatch_lines does an assertion internally
result.stdout.fnmatch_lines([
'test_log_cli_default_level.py PASSED',
'test_log_cli_default_level.py*',
'PASSED', # 'PASSED' on its own line because the log message prints a new line
])
result.stderr.fnmatch_lines([
result.stdout.fnmatch_lines([
'*WARNING message will be shown*',
])
assert "INFO message won't be shown" not in result.stderr.str()
assert "INFO message won't be shown" not in result.stdout.str()
# make sure that that we get a '0' exit code for the testsuite
assert result.ret == 0
@ -213,12 +214,13 @@ def test_log_cli_level(testdir):
# fnmatch_lines does an assertion internally
result.stdout.fnmatch_lines([
'test_log_cli_level.py PASSED',
'test_log_cli_level.py*',
'PASSED', # 'PASSED' on its own line because the log message prints a new line
])
result.stderr.fnmatch_lines([
result.stdout.fnmatch_lines([
"* This log message will be shown"
])
for line in result.errlines:
for line in result.outlines:
try:
assert "This log message won't be shown" in line
pytest.fail("A log message was shown and it shouldn't have been")
@ -232,12 +234,13 @@ def test_log_cli_level(testdir):
# fnmatch_lines does an assertion internally
result.stdout.fnmatch_lines([
'test_log_cli_level.py PASSED',
'test_log_cli_level.py*',
'PASSED', # 'PASSED' on its own line because the log message prints a new line
])
result.stderr.fnmatch_lines([
result.stdout.fnmatch_lines([
"* This log message will be shown"
])
for line in result.errlines:
for line in result.outlines:
try:
assert "This log message won't be shown" in line
pytest.fail("A log message was shown and it shouldn't have been")
@ -270,12 +273,13 @@ def test_log_cli_ini_level(testdir):
# fnmatch_lines does an assertion internally
result.stdout.fnmatch_lines([
'test_log_cli_ini_level.py PASSED',
'test_log_cli_ini_level.py*',
'PASSED', # 'PASSED' on its own line because the log message prints a new line
])
result.stderr.fnmatch_lines([
result.stdout.fnmatch_lines([
"* This log message will be shown"
])
for line in result.errlines:
for line in result.outlines:
try:
assert "This log message won't be shown" in line
pytest.fail("A log message was shown and it shouldn't have been")