Pytest caplog (log output)

4.2k views Asked by At

Need to get logs output for unit-tests with Python pytest. It works if I pass caplog as an argument to regular test_... function. How to pass it to Test... class method?

This code works fine:

def test_foo(caplog):
    assert 'warning text' in caplog.text

This gives empty caplog.text:

class TestFoo:
    def test_foo(self, caplog):
        assert 'warning text' in caplog.text

Tried this as well (found here: pytest to insert caplog fixture in test method) - still empty:

class TestFoo:
    @pytest.fixture(autouse=True)
    def inject_fixtures(self, caplog):
        self._caplog = caplog

    def test_foo(self):
        assert 'warning text' in self._caplog.responses[0]
        assert 'warning text' in self._caplog.messages[0]

Last one fails as responses and messages are empty lists. While caplog itself is an existing _pytest.logging.LogCaptureFixture object but with empty content.

EDITED: The issue is that I capture logs not in the method itself but in other fixture that prepares data for the test method. So the question is - how to capture logs in other fixture?

class TestRotaion:
    @pytest.fixture
    def foo_fixture(self, caplog):
        ...
        self._caplog = caplog
        ...

    def test_foo(self, foo_fixture):
        assert 'text' in caplog.text

Tried this as well but same - empty caplog.

@pytest.fixture
@pytest.mark.usefixtures('caplog')
def foo_fixture(self, caplog):
    ...
2

There are 2 answers

0
Igor On BEST ANSWER

The issues was that in fixture I saved not the text from caplog but caplog itself - it was already empty when main test func started.

So working code is:

class TestFoo:
    @pytest.fixture
    def foo_fixture(self, caplog):
        ...
        self._caplog_text = caplog.text
        ...
    
    def test_foo(self, foo_fixture):
        assert 'text' in self._caplog_text
2
Anton Petrov On

When using caplog fixture with a Test class, you need to use the pytest.mark.usefixtures marker to indicate that you want to use the fixture.

import pytest

class TestFoo:
    @pytest.mark.usefixtures("caplog")
    def test_foo(self, caplog):
        assert 'warning text' in caplog.text