You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pytest无法捕获被测函数日志的问题求助

pytest caplog无法捕获被测函数日志的解决方案

问题核心原因:你的被测函数中,logger依赖propagate=True将日志传递给root logger,但root logger默认级别为WARNING,会过滤掉INFO级别的日志;同时该logger自身未添加任何handler,导致日志无法被正常emit,最终caplog捕获不到。

以下是几种可行的解决方案:

方案一:调整root logger级别,允许传递的日志被捕获

修改测试代码,在上下文管理器中同时设置目标logger和root logger的级别为INFO,确保传递过来的INFO日志不会被过滤:

class Test():
    def test_function(self, caplog):
        # 同时设置目标logger和root logger的级别为INFO
        with caplog.at_level(logging.INFO, logger="my-logger"), \
             caplog.at_level(logging.INFO, logger="root"):
            function_to_test()
        assert caplog.text != ""

方案二:禁用logger的propagate,让caplog直接捕获

让目标logger的日志不传递到root,由caplog直接捕获该logger的输出:

class Test():
    def test_function(self, caplog):
        logger = logging.getLogger("my-logger")
        # 保存原始propagate设置,测试后恢复避免影响其他用例
        original_propagate = logger.propagate
        logger.propagate = False
        try:
            with caplog.at_level(logging.INFO, logger="my-logger"):
                function_to_test()
            assert caplog.text != ""
        finally:
            logger.propagate = original_propagate

方案三:重构代码,分离logger配置与业务逻辑

将logger的配置从函数内部移到模块级别(或独立配置文件),避免在业务函数中硬编码日志配置,让测试时caplog可以正常工作:

import logging

# 模块级别配置logger,仅初始化一次
logger = logging.getLogger("my-logger")
logger.setLevel(logging.INFO)
logger.propagate = True

def function_to_test():
    message = "log me"
    logger.info(message)

class Test():
    def test_function(self, caplog):
        with caplog.at_level(logging.INFO, logger="my-logger"):
            function_to_test()
        assert caplog.text != ""

方案四:给目标logger添加caplog的handler

直接将caplog的handler绑定到目标logger,确保日志能被捕获:

class Test():
    def test_function(self, caplog):
        logger = logging.getLogger("my-logger")
        # 添加caplog的handler到目标logger
        logger.addHandler(caplog.handler)
        try:
            with caplog.at_level(logging.INFO, logger="my-logger"):
                function_to_test()
            assert caplog.text != ""
        finally:
            # 测试后移除handler,避免影响其他测试用例
            logger.removeHandler(caplog.handler)

内容的提问来源于stack exchange,提问作者Joseph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 17:55:18