【问题标题】:Why is caplog.text empty, even though the function I'm testing is logging?为什么 caplog.text 为空,即使我正在测试的功能正在记录?
【发布时间】:2020-05-09 13:45:21
【问题描述】:

我正在尝试使用 pytest 来测试我的函数是否正在记录预期的文本,例如地址为 this question(pyunit 等效项为 assertLogs)。在pytest logging documentation 之后,我将caplog 夹具传递给测试仪。文档指出:

最后,在测试运行期间发送到记录器的所有日志都以 logging.LogRecord 实例和最终日志文本的形式在夹具上可用。

我正在测试的模块是:

import logging
logger = logging.getLogger(__name__)

def foo():
    logger.info("Quinoa")

测试者是:

def test_foo(caplog):
    from mwe16 import foo
    foo()
    assert "Quinoa" in caplog.text

我希望这个测试能够通过。但是,使用pytest test_mwe16.py 运行测试会显示由于caplog.text 为空而导致测试失败:

============================= test session starts ==============================
platform linux -- Python 3.7.3, pytest-5.3.0, py-1.8.0, pluggy-0.13.0
rootdir: /tmp
plugins: mock-1.12.1, cov-2.8.1
collected 1 item

test_mwe16.py F                                                          [100%]

=================================== FAILURES ===================================
___________________________________ test_foo ___________________________________

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

    def test_foo(caplog):
        from mwe16 import foo
        foo()
>       assert "Quinoa" in caplog.text
E       AssertionError: assert 'Quinoa' in ''
E        +  where '' = <_pytest.logging.LogCaptureFixture object at 0x7fa86853e8d0>.text

test_mwe16.py:4: AssertionError
============================== 1 failed in 0.06s ===============================

尽管foo() 向记录器发送文本,为什么caplog.text 为空?如何使用pytest 以便caplog.text 捕获记录的文本,或以其他方式验证文本是否被记录?

【问题讨论】:

  • 您的日志记录可能是:未配置、日志级别错误、已过滤或未处理。
  • @KlausD。 pytest 不应该解决这个问题吗?我认为 pytest 会添加必要的处理程序来测试日志记录。从文档中:“在测试运行期间发送到记录器的所有日志都可以在夹具上使用”。那里没有关于配置或日志级别的信息;但也许文档不清楚。
  • 虽然pytest 添加了一个自定义处理程序来捕获日志记录,但它不会更改根记录器级别(默认设置为WARNING)。因此它无法访问记录,因为它们没有被传播:foo() 将信息记录发送到记录器,但它不会将它传递给任何处理程序,包括caplog 的处理程序。如果要打开捕获,请在例如设置 logging.root.setLevel(logging.DEBUG)一个会话范围的夹具。

标签: python unit-testing testing logging pytest


【解决方案1】:

在logger设置中,请设置logger.propagate=True

【讨论】:

    【解决方案2】:

    这里的文档不清楚。通过反复试验,尽管有“在测试运行期间发送到记录器的所有日志都可用”文本,但它仍然只捕获具有某些日志级别的日志。 实际上要捕获所有日志,需要使用caplog.set_levelcaplog.at_level 上下文管理器为捕获的日志消息设置日志级别,以便测试模块变为:

    import logging
    def test_foo(caplog):
        from mwe16 import foo
        with caplog.at_level(logging.DEBUG):
            foo()
        assert "Quinoa" in caplog.text
    

    现在,测试通过了:

    ============================= test session starts ==============================
    platform linux -- Python 3.7.3, pytest-5.3.0, py-1.8.0, pluggy-0.13.0
    rootdir: /tmp
    plugins: mock-1.12.1, cov-2.8.1
    collected 1 item
    
    test_mwe16.py .                                                          [100%]
    
    ============================== 1 passed in 0.04s ===============================
    

    【讨论】:

    • 在您的记录器设置中,确保 logger.propagate=True
    猜你喜欢
    • 2017-01-04
    • 2016-08-12
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    相关资源
    最近更新 更多