【问题标题】:How to prevent logging to file and capture logs for assertions using Pytest如何使用 Pytest 防止日志记录到文件并捕获断言日志
【发布时间】:2021-12-07 11:19:52
【问题描述】:

我有一套针对 python 模块的单元测试,并使用 Pytest 来运行这些测试。我现在开始在我的库中使用标准日志库,需要帮助解决两个问题:

  1. 如何在运行测试套件时防止日志进入文件,防止文件增长并防止在真实日志文件中出现无用的条目。
  2. 如何在单元测试中捕获日志,以便能够对库生成的日志运行断言。

我尝试测试的模块将__init__.py 中的日志库配置为登录文件并使用 info 方法在模块代码中记录条目。这很好用,当我运行代码时,正确的日志条目会出现在文件中。 -- 见下面的代码--

我曾尝试在 pytest 中使用caplog 夹具--参见下面的代码和输出-- 但我得到的效果是:

  • 日志条目包含在文件中(使用 caplog 和所有其他测试在运行中生成的日志)
  • caplog.text 为空

单元测试代码

import library.module

class TestFunction:

    def test_something_else(self):
        library.module.function():
        assert True

    def test_logs(self,caplog)
        library.module.function():
        assert "desired" in caplog.text

测试输出

(...)
>     assert "desired" in caplog.text
E     AssertionError: assert 'desired' in ''
E      + where '' = <_pytest.logging.LogCaptureFixture object at (...).text
(...)

运行测试套件后的日志条目

2021-12-07 11:10:05,915 - library.module - INFO - desired
2021-12-07 11:10:05,917 - library.module - INFO - desired

日志模块配置

__init__.py

import logging.config
import yaml

with open("logging.yaml") as f:
    conf_dict = yaml.safe_load(f)
    logging.config.dictConfig(conf_dict)

logging.yaml

version: 1
formatters:
    simple:
        format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:    
    training:
        class: logging.FileHandler
        level: DEBUG
        formatter: simple
        filename: logs/test_log
loggers:
    library.module:
        level: DEBUG
        handlers: [training]
        propagate: no
root:
    level: DEBUG
    handlers: []

被测模块

import logging
logger = logging.getLogger(__name__)

def function():
    logger.info("desired")

文件结构

.
├── library
│   ├── module.py
│   └── __init__.py
├── tests
│   └── test_module.py
└── logs
    └── test_log

【问题讨论】:

  • 我已经能够解决第二个问题。测试现在正确捕获日志条目,并且 caplog.text 包含正确的文本。错误出现在配置中,其中library.module 记录器设置为propagate: no,通过将其设置为yes,测试和caplog.text 工作正常。但是第一个问题仍在发生,每次我运行单元测试时,日志文件都会获取我不希望出现的日志条目

标签: python unit-testing pytest


【解决方案1】:

为避免写入日志文件,我建议您在 test_module.py 中简单地模拟记录器并在测试中使用它,如下所示:

import pytest
import library.module

@pytest.fixture
def logger(mocker):
    return mocker.patch("library.module.logger.info")


class TestFunction:

    def test_something_else(self):
        library.module.function():
        assert True

    def test_logs(self,logger)
        library.module.function():
        logger.assert_called_with("desired")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多