question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Pytest's caplog fixture doesn't seem to work

See original GitHub issue

Summary

Pytest’s caplog fixture is a critical part of testing. I’d love to move to loguru, but loguru doesn’t seem to work with caplog.

I’m not sure if this is user error (perhaps it’s documented somewhere? I haven’t been able to find it.), if it is some design oversight/choice, or if the problem is actually on pytest’s end.

Expected Result

Users should be able to use loguru as a drop-in replacement for the stdlib logging package and have tests that use the caplog fixture still work.

Actual Result

Drop-in replacement causes tests that use the caplog pytest fixture to fail.

Steps to Reproduce

Base test file

# test_demo.py
import pytest
import logging
logger = logging.getLogger()
logger.addHandler(logging.StreamHandler())
# from loguru import logger

def some_func(a, b):
    if a < 1:
        logger.warning("Oh no!")
    return a + b

def test_some_func_logs_warning(caplog):
    assert some_func(-1, 2) == 1
    assert "Oh no!" in caplog.text

if __name__ == "__main__":
    some_func(-1, 1)
    print("end")

Without Loguru:

$ python test_demo.py
Oh no!
end
(.venv) Previous Dir: /home/dthor
09:59:56 dthor@Thorium /home/dthor/temp/loguru
$ pytest
========================== test session starts ==========================
platform linux -- Python 3.6.7, pytest-4.3.0, py-1.8.0, pluggy-0.8.1
rootdir: /home/dthor/temp/loguru, inifile:
collected 1 item

test_demo.py .                                                    [100%]

======================= 1 passed in 0.03 seconds ========================

With Loguru:

Adjust test_demo.py by commenting out stdlib logging and uncommenting loguru:

...
# import logging
# logger = logging.getLogger()
# logger.addHandler(logging.StreamHandler())
from loguru import logger
...
$ python test_demo.py
2019-02-22 10:02:35.551 | WARNING  | __main__:some_func:9 - Oh no!
end
(.venv) Previous Dir: /home/dthor
10:02:35 dthor@Thorium /home/dthor/temp/loguru
$ pytest
========================== test session starts ==========================
platform linux -- Python 3.6.7, pytest-4.3.0, py-1.8.0, pluggy-0.8.1
rootdir: /home/dthor/temp/loguru, inifile:
collected 1 item

test_demo.py F                                                    [100%]

=============================== FAILURES ================================
______________________ test_some_func_logs_warning ______________________

caplog = <_pytest.logging.LogCaptureFixture object at 0x7f8e8b620438>

    def test_some_func_logs_warning(caplog):
        assert some_func(-1, 2) == 1
>       assert "Oh no!" in caplog.text
E       AssertionError: assert 'Oh no!' in ''
E        +  where '' = <_pytest.logging.LogCaptureFixture object at 0x7f8e8b620438>.text

test_demo.py:14: AssertionError
------------------------- Captured stderr call --------------------------
2019-02-22 10:02:37.708 | WARNING  | test_demo:some_func:9 - Oh no!
======================= 1 failed in 0.20 seconds ========================

Version information

$ python --version
Python 3.6.7
(.venv) Previous Dir: /home/dthor
10:10:03 dthor@Thorium /home/dthor/temp/loguru
$ pip list
Package                Version
---------------------- -----------
ansimarkup             1.4.0
atomicwrites           1.3.0
attrs                  18.2.0
better-exceptions-fork 0.2.1.post6
colorama               0.4.1
loguru                 0.2.5
more-itertools         6.0.0
pip                    19.0.3
pkg-resources          0.0.0
pluggy                 0.8.1
py                     1.8.0
Pygments               2.3.1
pytest                 4.3.0
setuptools             40.8.0
six                    1.12.0
(.venv) Previous Dir: /home/dthor
10:10:07 dthor@Thorium /home/dthor/temp/loguru
$ uname -a
Linux Thorium 4.4.0-17763-Microsoft #253-Microsoft Mon Dec 31 17:49:00 PST 2018 x86_64 x86_64 x86_64 GNU/Linux
(.venv) Previous Dir: /home/dthor
10:11:33 dthor@Thorium /home/dthor/temp/loguru
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.2 LTS
Release:        18.04
Codename:       bionic

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:29 (18 by maintainers)

github_iconTop GitHub Comments

9reactions
Delgancommented, Jan 19, 2022

Please, note the documentation has been updated. The recommended way to integrate Loguru with pytest is to override the caplog fixture this way:

@pytest.fixture
def caplog(caplog):
    handler_id = logger.add(caplog.handler, format="{message}")
    yield caplog
    logger.remove(handler_id)

Using PropagateHandler could result in dead-lock if inadvertently combined with InterceptHandler see #474.

5reactions
alextremblaycommented, Oct 16, 2021

Thank you all for code samples, they’re incredibly useful. I just want to share my own, in case any of you find it useful:

# conftest.py
import logging

import pytest
from loguru import logger

@pytest.fixture
def caplog(caplog):
    """
    override and wrap the caplog fixture with one of our own
    """
    logger.remove() # remove default handler, if it exists
    logger.enable("") # enable all logs from all modules
    logging.addLevelName(5, "TRACE") # tell python logging how to interpret TRACE logs
    class PropogateHandler(logging.Handler):
        def emit(self, record):
            logging.getLogger(record.name).handle(record)
    logger.add(PropogateHandler(), format="{message} {extra}", level="TRACE") # shunt logs into the standard python logging machinery
    caplog.set_level(0) # Tell logging to handle all log levels
    yield caplog
Read more comments on GitHub >

github_iconTop Results From Across the Web

Why is caplog.text empty, even though the function I'm testing ...
Following the pytest logging documentation, I am passing the caplog fixture to the tester. The documentation states: Lastly all the logs sent to ......
Read more >
Switching from standard logging to loguru
Making things work with Pytest and caplog . pytest is a very common testing framework. The caplog fixture captures logging output so that...
Read more >
9 pytest tips and tricks to take your tests to the next level
Use capsys to test for stdout and stderr messages ... Just like with caplog , capsys is a built-in fixture that we use...
Read more >
pytest — KB Software Documentation 0.1.01 documentation
caplog.record_tuples is nice and simple with the caplog fixture: ... This doesn't seem to work using setup.cfg or pytest.ini (I had problems with ......
Read more >
pytest Documentation - Read the Docs
overridden this way even if the test doesn't use it directly (doesn't mention it in the function prototype). Override a parametrized fixture ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found