Control logging output during Python tests
Separate suppressing log records from hiding pytest output, restore logging state after tests, and keep caplog assertions meaningful.
First decide whether you want to stop records from being emitted or simply hide them in the test report. logging.disable() controls standard logging globally; pytest options control capture and presentation. Those are different operations.
Temporarily suppress standard log levels
import logging
previous_threshold = logging.root.manager.disable
try:
logging.disable(logging.CRITICAL)
# Run the code whose standard logging should be suppressed.
finally:
logging.disable(previous_threshold)
This suppresses records at CRITICAL and below, including CRITICAL itself. Custom levels above that threshold are not covered. logging.disable(logging.NOTSET) removes the global override, but restoring the prior value is more careful when a test inherits an existing configuration.
The override affects the process, not just one test function. Keep its lifetime short, and consider concurrent work before changing global logging state.
Control pytest's presentation
python -m pytest --show-capture=no
python -m pytest -p no:logging
The first hides captured output in failure reports; it does not stop application logging. The second disables pytest's logging plugin, including its log-capture facilities. It does not automatically silence handlers configured by the application, and the caplog fixture is then unavailable.
To disable live log display while retaining capture, configure:
[pytest]
log_cli = false
Captured records may still be shown for failed tests unless the reporting options hide them.
Suppress a specific output handler
If the application has separate console and file handlers, change only the console handler's threshold or filter and restore it afterward. Removing all root handlers is not a reliable mute switch: child loggers can have their own handlers, the fallback lastResort handler can emit warnings, and module-level convenience calls may install a default handler.
For a known console handler, the basic pattern is:
previous_level = console_handler.level
try:
console_handler.setLevel(logging.CRITICAL + 1)
# Standard severity records no longer reach this handler.
finally:
console_handler.setLevel(previous_level)
Here console_handler must refer to the application's actual console handler; custom higher levels require their own policy.
FAQ
How does disable() differ from setLevel()? disable() sets a process-wide threshold. setLevel() affects a logger or handler and interacts with inheritance and propagation. Choose the scope you intend rather than changing all logging for convenience.
How do I test that a message was logged? Keep logging enabled for a caplog test and assert on its captured records. A mock can verify a logger method call, but that does not prove a record reached a handler.
What about Django tests? Configure the relevant logger and handlers in test settings before startup. Changing LOGGING with override_settings alone should not be assumed to reconfigure already-created handlers. LOGGING_CONFIG = None disables Django's automatic logging configuration, not all logging output.
References
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan