Testing logging output with pytest
Solution 1
I don't know why this didn't work when I tried it before, but this solution works for me now:
In test_module.py:
import logging
from module import run_function
LOGGER = logging.getLogger(__name__)
def test_func(caplog):
LOGGER.info('Testing now.')
run_function()
assert 'Something bad happened!' in caplog.text
Solution 2
test_module.py
should look like this:
import logging
from module import run_function
LOGGER = logging.getLogger(__name__)
def test_func(caplog):
with caplog.at_level(logging.WARNING):
run_function()
assert 'Something bad happened!' in caplog.text
or:
import logging
from module import run_function
LOGGER = logging.getLogger(__name__)
def test_func(caplog):
caplog.set_level(logging.WARNING):
run_function()
assert 'Something bad happened!' in caplog.text
Documentation for pytest capture logging is here
Solution 3
In your logging set up, check propagate
is set to True, otherwise caplog handler is not able to see the logging message.
Solution 4
I also want to add to this thread for anybody in the future coming across this. You may need to use
@pytest.fixture(autouse=True)
as a decorator on your test so the test has access to the caplog fixture.
lauren.marietta
Updated on November 12, 2021Comments
-
lauren.marietta over 2 years
I am trying to write a test, using pytest, that would check that a specific function is writing out a warning to the log when needed. For example:
In module.py:
import logging LOGGER = logging.getLogger(__name__) def run_function(): if something_bad_happens: LOGGER.warning('Something bad happened!')
In test_module.py:
import logging from module import run_function LOGGER = logging.getLogger(__name__) def test_func(): LOGGER.info('Testing now.') run_function() ~ somehow get the stdout/log of run_function() ~ assert 'Something bad happened!' in output
I have seen that you can supposedly get the log or the stdout/stderr with pytest by passing
capsys
orcaplog
as an argument to the test, and then using eithercapsus.readouterr()
orcaplog.records
to access the output.However, when I try those methods, I only see "Testing now.", and not "Something bad happened!". It seems like the logging output that is happening within the call to
run_function()
is not accessible fromtest_func()
?The same thing happens if I try a more direct method, such as
sys.stdout.getvalue()
. Which is confusing, becauserun_function()
is writing to the terminal, so I would think that would be accessible fromstdout
...?Basically, does anyone know how I can access that 'Something bad happened!' from within
test_func()
?