使用模拟获取所有日志输出

2024-01-27

我想用模拟获取所有日志输出。我搜索过,但是 只找到了显式模拟logging.info或logging.warn的方法。

我需要所有输出,无论设置的日志记录级别如何。

def test_foo():

   def my_log(...):
      logs.append(...)

   with mock.patch('logging.???', my_log):
        ...

在我们的库中,我们使用这个:

import logging
logger=logging.getLogger(__name__)

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

pytest

如果您正在使用以下方式编写测试pytest,看一下名为caplog这将为您捕获日志记录。它捕获所有发出的日志记录,然后您可以通过以下方式访问这些记录caplog.records列表。每个元素都是一个实例logging.LogRecord,这样您就可以轻松访问任何LogRecord属性 https://docs.python.org/3/library/logging.html#logrecord-attributes。例子:

# spam.py

import logging
logger=logging.getLogger(__name__)

def foo():
    logger.info('bar')


# tests.py

import logging
from spam import foo

def test_foo(caplog):
    foo()
    assert len(caplog.records) == 1
    record = next(iter(caplog.records))
    assert record.message == 'bar'
    assert record.levelno == logging.INFO
    assert record.module == 'spam'
    # etc

Install

该装置首次引入于pytest插件名为pytest-capturelog现在已被废弃。幸运的是,它有一个像样的叉子,名叫pytest-catchlog, 已合并到pytest==3.3.0 https://docs.pytest.org/en/latest/changelog.html#pytest-3-3-0-2017-11-23最近。因此,如果您使用最新版本pytest,您已经可以开始了;对于旧版本的pytest, install pytest-catchlog来自 PyPI https://pypi.python.org/pypi/pytest-catchlog/.

Docs

眼下,pytest不提供任何文档caplog固定装置(或者至少我找不到),所以你可以参考pytest-catchlog's 文档 https://pypi.python.org/pypi/pytest-catchlog/.

Plain unittest

If pytest不是一个选项,我不会修补logging完全 - 您可以简单地添加一个自定义处理程序来记录所有传入的日志。一个小例子:

# utils.py

import logging


class RecordsCollector(logging.Handler):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.records = []

    def emit(self, record):
        self.records.append(record)


# tests.py

import logging
import unittest
from utils import RecordsCollector
from spam import foo


class SpamTests(unittest.TestCase):

    def setUp(self):
        self.collector = RecordsCollector()
        logging.getLogger('spam').addHandler(self.collector)

    def tearDown(self):
        logging.getLogger('spam').removeHandler(self.collector)

    def test_foo(self):
        foo()
        # same checks as in the example above
        self.assertEqual(len(self.collector.records), 1)
        record = next(iter(self.collector.records))
        self.assertEqual(record.message, 'bar')
        self.assertEqual(record.levelno, logging.INFO)
        self.assertEqual(record.module, 'spam')


if __name__ == '__main__':
    unittest.main()

然后,您可以扩展自定义处理程序并实现您需要的任何逻辑,例如收集记录dict将日志级别映射到记录列表,或添加contextmanager实现,这样您就可以开始和停止捕获测试中的记录:

from contextlib import contextmanager

@contextmanager
def record_logs():
    collector = RecordsCollector()
    logging.getLogger('spam').addHandler(collector)
    yield collector
    logging.getLogger('spam').removeHandler(collector)


def test_foo(self):
    with utils.record_logs() as collector:
        foo()
        self.assertEqual(len(collector.records), 1)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用模拟获取所有日志输出 的相关文章

随机推荐

  • 边距和填充之间的区别?

    到底有什么区别margin and padding在CSS中 看来确实没有多大用处 您能否举个例子来说明差异所在 以及为什么了解差异很重要 padding是内容和内容之间的空间border 然而margin是边界之外的空间 这是我从谷歌快速
  • 如何在 Spring Rest Controller 中区分部分更新的 null 值和未提供的值

    当使用 Spring Rest Controller 中的 PUT 请求方法部分更新实体时 我试图区分 null 值和未提供的值 考虑以下实体作为示例 Entity private class Person Id GeneratedValu
  • 为有效信用卡生成随机数的好方法是什么?

    我正在用 Java 开发一套用于验证和使用信用卡的工具 到目前为止 我支持 卢恩验证 日期验证 简单到期 基于品牌 Visa MasterCard 等 的卡代码长度验证 CVV CVC CID 信用卡号长度验证 基于品牌 BIN IIN 验
  • pandas groupby 可以将 DataFrame 转换为 Series 吗?

    我想使用 pandas 和 statsmodels 在数据帧的子集上拟合线性模型并返回预测值 但是 我无法找出正确的 pandas 习惯用法 这是我正在尝试做的事情 import pandas as pd import statsmodel
  • 如何为 AWS Lambda nodejs 运行时构建单个 js 文件

    我们正在研究一个项目 框架 https github com jaws stack JAWS tree v1 0有助于在 AWS Lambda 中部署和维护代码 我想将 lambda 函数的所有 node js 代码构建 捆绑到一个 js
  • Firebase - 如何一次删除多个条目?

    我该如何删除all给定推送 ID 的条目 例如 假设KoxoxwTqfb50E1Gvi9F推送 ID 位于我的数据库的许多位置 即在许多键下 我想删除所有条目KoxoxwTqfb50E1Gvi9F立即而不是静态删除所有条目 因为我知道它们的
  • 如何在 useEffect 中使用 setState 进行 API 调用后执行函数?

    我是一个 React 新手 学习了 30 个小时 有一些基本的 Javascript 背景 现在我正在学习一门课程 并试图 离开 这条路 但我很好奇如何实现我的预期目标 有一个 Memegenerator 它在渲染开始时从 API 获取所有
  • Magento 中不允许序列化?

    当我在 Magento 中打开缓存时 出现以下异常 不允许序列化 Mage Core Model Layout Element 异常发生在app code core Mage Page Block Template Links php 在线
  • 使用 Python 放置 PMML

    我有一个简单的PMML http en wikipedia org wiki Predictive Model Markup Language我想要的文件PUT到评分服务器 这里是curl call curl X PUT data bina
  • 如何使用 kubectl cmd 获取 git commit sha1?

    如何使用 kubectl 命令获取特定 pod 的提交 sha1 例如 kubectl get git commit sha1 pod name 目前还没有办法使用 kubectl 来实现你想要的 他们唯一可能的方法是如果你的 docker
  • 在 matplotlib 中向日期格式的时间序列添加垂直线

    我正在尝试向时间序列图中添加一条红色垂直线 其中 x 轴格式为 Y m d 我想添加该行的日期是 2013 年 5 月 14 日 只需在 plt show 之前添加一行 plt axvline x 2013 05 14 or plt axv
  • 如何在 C# 中对文件进行哈希处理

    如何使用 C 对文件进行哈希处理 有什么可用的 md5 crc sha1 等 是否有我应该继承的接口 我想对多个文件进行校验和并将其存储在数据库中 并使用我自己的两个校验和 哈希 1 如何使用 C 对文件进行哈希处理 您可以使用 NET 类
  • Rollup:从外部模块捆绑/嵌入 wasm 代码

    使用 rollup 我尝试捆绑一个 typescript 库 该库导入并调用包含 wasm 文件的 npm 模块 只有生成的包不包含 wasm 文件内容的痕迹 我怎样才能强制它捆绑网络程序集 这是我尝试过的关键文件 typescript s
  • 深度查找或搜索 JSON 中任何级别的键并替换其在 C# 中的值

    我也被一个问题所困扰 我能够将嵌套的 JSON 转换为 key Value 但现在我想将其转换回原来的 json 格式 由于我的问题 我无法使用 C 对象模型来执行此操作 因为我拥有的 JSON 文件是动态的 并且其结构会随着时间的推移而变
  • Ruby Webrick HTTP 身份验证

    我怎样才能做同样的身份验证工作这一页 http microjet ath cx webrickguide html HTTP Authentication html使用这样的子类 class Configuration lt HTTPSer
  • 为什么 std::iterator 被弃用?

    模板类std iterator http en cppreference com w cpp iterator iterator在 C 17 中已被弃用 为什么这样 这是一个方便的方法来确保std iterator traits http
  • d3.js v4,如何在鼠标悬停时有一条线跟随鼠标,同时也有一个圆圈跟随路径?

    这是我的 js 小提琴 https jsfiddle net DerNalia 3wzLv9yg 1 https jsfiddle net DerNalia 3wzLv9yg 1 我一直在尝试从这里解释代码 带有鼠标悬停工具提示的多系列折线
  • Bootstrap打印CSS去除背景颜色

    当我使用引导程序时 当我尝试打印页面时 它会从所有内容中删除背景颜色 我网站上的几乎所有内容都使用引导类 因此我想避免在引导程序之外使用大量手动 CSS 我发现 bootstrap 使用 media print删除背景颜色 我也使用引导主题
  • std::integral_constant 的否定

    抱歉问了这么简单的问题 但我无法轻松找到答案 谷歌没有说任何关于 C 否定积分常量 和类似查询的有趣内容 C 11 中是否有任何特征使得std true type from std false type反之亦然 换句话说 我想要一些更具可读
  • 使用模拟获取所有日志输出

    我想用模拟获取所有日志输出 我搜索过 但是 只找到了显式模拟logging info或logging warn的方法 我需要所有输出 无论设置的日志记录级别如何 def test foo def my log logs append wit