31

We have recently switched to py.test for python testing (which is fantastic btw). However, I'm trying to figure out how to control the log output (i.e. the built-in python logging module). We have pytest-capturelog installed and this works as expected and when we want to see logs we can pass --nologcapture option.

However, how do you control the logging level (e.g. info, debug etc.) and also filter the logging (if you're only interested in a specific module). Is there existing plugins for py.test to achieve this or do we need to roll our own?

Thanks, Jonny

jjh
  • 554
  • 1
  • 5
  • 12
  • 1
    pytest-capturelog appears to have been replaced by https://pypi.python.org/pypi/pytest-catchlog/ This is mentioned in a number of comments below, but I initially missed this information and attempted to use pytest-capturelog. I'm leaving this comment hoping it'll be more visible and save the next guy from making my mistake. – cledoux Jun 06 '17 at 20:54
  • 2
    Since version 3.3, `pytest-catchlog` is included in the `pytest` framework, so you don't need anything in addition. See [Logging](https://docs.pytest.org/en/latest/logging.html) section in the docs. – hoefling Aug 02 '18 at 10:30

5 Answers5

10

Installing and using the pytest-capturelog plugin could satisfy most of your pytest/logging needs. If something is missing you should be able to implement it relatively easily.

hpk42
  • 21,501
  • 4
  • 47
  • 53
  • I just tried this with pytest 3.0.6. it worked fine but barks a lot: /pytest_capturelog.py:171 'pytest_runtest_makereport' hook uses deprecated __multicall__ argument WC1 None pytest_funcarg__caplog: declaring fixtures using "pytest_funcarg__" prefix is deprecated and scheduled to be removed in pytest 4.0. Please remove the prefix and use the @pytest.fixture decorator instead. ... – moin moin Feb 17 '17 at 08:57
  • 1
    Looks like there is a fork that fixes this issue: https://pypi.python.org/pypi/pytest-catchlog/ – Danilo Bargen Mar 03 '17 at 10:40
  • 4
    You don't need any plugins for that, because all this plugins are deprecated and `the functionality of this plugin has been merged to the pytest core` as said here https://github.com/eisensheng/pytest-catchlog (Fork of `pytest-capturelog`) – lucidyan Nov 13 '18 at 15:23
10

As Holger said you can use pytest-capturelog:

def test_foo(caplog):
    caplog.setLevel(logging.INFO)
    pass

If you don't want to use pytest-capturelog you can use a stdout StreamHandler in your logging config so pytest will capture the log output. Here is an example basicConfig

logging.basicConfig(level=logging.DEBUG, stream=sys.stdout)
Aron Curzon
  • 2,524
  • 2
  • 19
  • 16
  • 3
    pytest-capturelog seems unmaintained and throws warnings. Looks like there is a fork that fixes this issue: https://pypi.python.org/pypi/pytest-catchlog/ – Danilo Bargen Mar 03 '17 at 10:40
  • @DaniloBargen *pytest* has integrated logging features as replacement of `pytest-capturelog` from version 3.3, as mentionned here: https://docs.pytest.org/en/latest/logging.html#release-notes – Jean-Francois T. Feb 14 '19 at 06:34
  • Hi, thanks for the hint. One remark: actually the method is called ```caplog.set_level(logging.INFO)``` (snake case). See: https://docs.pytest.org/en/6.2.x/logging.html#caplog-fixture – andi0815 Jan 31 '22 at 15:16
8

A bit of a late contribution, but I can recommend pytest-logging for a simple drop-in logging capture solution. After pip install pytest-logging you can control the verbosity of the your logs (displayed on screen) with

$ py.test -s -v tests/your_test.py
$ py.test -s -vv tests/your_test.py
$ py.test -s -vvvv tests/your_test.py

etc... NB - the -s flag is important, without it py.test will filter out all the sys.stderr information.

danodonovan
  • 19,636
  • 10
  • 70
  • 78
6

Pytest now has native support for logging control via the caplog fixture; no need for plugins.

You can specify the logging level for a particular logger or by default for the root logger:

import pytest

def test_bar(caplog):
    caplog.set_level(logging.CRITICAL, logger='root.baz')

Pytest also captures log output in caplog.records so you can assert logged levels and messages. For further information see the official documentation here and here.

Alaya
  • 272
  • 1
  • 4
  • 10
1

A bit of an even later contribution: you can try pytest-logger. Novelty of this plugin is logging to filesystem: pytest provides nodeid for each test item, which can be used to organize test session logs directory (with help of pytest tmpdir facility and it's testcase begin/end hooks).

You can configure multiple handlers (with levels) for terminal and filesystem separately and provide own cmdline options for filtering loggers/levels to make it work for your specific test environment - e.g. by default you can log all to filesystem and small fraction to terminal, which can be changed on per-session basis with --log option if needed. Plugin does nothing by default, if user defines no hooks.

aurzenligl
  • 181
  • 1
  • 7