简体   繁体   English

使用 pytest 测试日志输出

[英]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.我正在尝试使用 pytest 编写一个测试,该测试将检查特定函数是否在需要时向日志写入警告。 For example:例如:

In module.py:在 module.py 中:

import logging
LOGGER = logging.getLogger(__name__)

def run_function():
    if something_bad_happens:
        LOGGER.warning('Something bad happened!')

In test_module.py:在 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.我已经看到,您可以通过将capsyscaplog作为测试的参数传递capsys caplog ,然后使用capsus.readouterr()caplog.records访问输出来获取日志或 stdout/stderr。

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() ?似乎无法从test_func()访问调用run_function()发生的日志输出?

The same thing happens if I try a more direct method, such as sys.stdout.getvalue() .如果我尝试更直接的方法,例如sys.stdout.getvalue() ,也会发生同样的事情。 Which is confusing, because run_function() is writing to the terminal, so I would think that would be accessible from stdout ...?这令人困惑,因为run_function()正在写入终端,所以我认为可以从stdout访问它......?

Basically, does anyone know how I can access that 'Something bad happened!'基本上,有谁知道我如何访问“发生了不好的事情!” from within test_func() ?test_func()

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:在 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

test_module.py should look like this: test_module.py应如下所示:

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 pytest 捕获日志的文档在这里

在您的日志记录设置中,检查propagate设置为 True,否则 caplog 处理程序无法看到日志消息。

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.作为测试中的装饰器,因此测试可以访问 caplog 夹具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM