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.