Reputation: 10069
I'm using pytest's Live Logs feature to see the logging records as they're generated. I'm currently setting the log level in the pytest.ini
file, as per the docs, using the log_cli_level
entry. However, it would be fairly practical to be able to change the log level from the code.
After some inspection of the pytest code, I can see it sets the self.log_cli_level
field in the LoggingPlugin
class. This plugin is registered with the pluginmanager here, with the key "logging-plugin"
.
I guess it would be a matter of accessing the plugin using the getplugin
method of the PytestPluginManager
to obtain the LoggingPlugin, but I'm afraid I have not found a way of accessing that manager.
Upvotes: 3
Views: 1048
Reputation: 66171
I'm afraid I have not found a way of accessing that manager.
Use the request
fixture to access the plugin manager in tests:
def test_spam(request):
mgr = request.session.config.pluginmanager
logging_plugin = mgr.get_plugin("logging-plugin")
However, this won't be necessary for changing the live log level (and IIRC changing LoggingPlugin.log_cli_level
will only have an effect in runtest hooks, not in the test cases or fixtures). The log capturing and live logging share the same log level, so simply use the caplog
fixture. Here's a simple example:
import logging
import pytest
logger = logging.getLogger(__name__)
def emit_logs():
logger.info('sample info')
logger.warning('sample warning')
logger.error('sample error')
logger.critical('sample critical')
def test_spam():
emit_logs()
will yield
-------------------------------- live log call --------------------------------
2020-12-11 16:27:41 [ INFO] sample info (test_spam.py:9)
2020-12-11 16:27:41 [ WARNING] sample warning (test_spam.py:10)
2020-12-11 16:27:41 [ ERROR] sample error (test_spam.py:11)
2020-12-11 16:27:41 [CRITICAL] sample critical (test_spam.py:12)
Now e.g. raising the level to CRITICAL
:
def test_spam(caplog):
caplog.set_level(logging.CRITICAL)
emit_logs()
yields only
-------------------------------- live log call --------------------------------
2020-12-11 16:27:41 [CRITICAL] sample critical (test_spam.py:12)
Using caplog
as context manager:
def test_spam(caplog):
with caplog.at_level(logging.ERROR):
emit_logs()
will yield
-------------------------------- live log call --------------------------------
2020-12-11 16:27:41 [ ERROR] sample error (test_spam.py:11)
2020-12-11 16:27:41 [CRITICAL] sample critical (test_spam.py:12)
Dynamic changing live log level also works,
def test_eggs(caplog):
with caplog.at_level(logging.WARNING):
logger.info("i am not logged")
logger.info("but i am")
as well as moving live log level switch to fixtures:
@pytest.fixture
def errors_only(caplog):
with caplog.at_level(logging.ERROR):
yield
@pytest.mark.usefixtures("errors_only")
def test_bacon():
logger.error("i am printed")
logger.info("but i am not")
Upvotes: 4