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.
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")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With