Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing logging output with pytest

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 or caplog as an argument to the test, and then using either capsus.readouterr() or caplog.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 from test_func()?

The same thing happens if I try a more direct method, such as sys.stdout.getvalue(). Which is confusing, because run_function() is writing to the terminal, so I would think that would be accessible from stdout...?

Basically, does anyone know how I can access that 'Something bad happened!' from within test_func()?

like image 927
lauren.marietta Avatar asked Nov 02 '18 20:11

lauren.marietta


People also ask

How do I use pytest logging?

By setting the log_cli configuration option to true , pytest will output logging records as they are emitted directly into the console. You can specify the logging level for which log records with equal or higher level are printed to the console by passing --log-cli-level .

What is Autouse in pytest?

pytest is a very robust framework that comes with lots of features. One such feature is the autouse fixtures, a.k.a xUnit setup on steroids. They are a special type of fixture that gets invoked automatically, and its main use case is to act as a setup/teardown function.


1 Answers

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 
like image 143
lauren.marietta Avatar answered Sep 23 '22 07:09

lauren.marietta