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

如何让Python unittest仅在测试失败时输出日志消息

问题根因

unittest --buffer的核心逻辑是测试执行前将sys.stdout/sys.stderr替换为内存缓冲区,测试通过则丢弃缓冲区内容,失败才将缓冲区内容打印到终端。
你在调用logging.basicConfig时指定了stream=sys.stdout,此时logging会将当前的原始stdout对象永久绑定到默认的日志Handler上,后续unittest替换sys.stdout的操作不会同步到logging的Handler配置,因此日志输出直接绕过了buffer机制,无论测试是否通过都会直接打印。

最简解决方案

我们可以通过一个代理流类,让日志始终输出到当前生效的sys.stdout,即可让logging的输出被unittest的buffer正常捕获:

import logging
import unittest
import sys

logger = logging.getLogger('abc')

# 自定义代理流,每次写入都指向当前的sys.stdout
class DelegatedStdout:
    def write(self, buf):
        sys.stdout.write(buf)
    def flush(self):
        sys.stdout.flush()

logging.basicConfig(
    format = '%(asctime)s %(module)s %(levelname)s: %(message)s',
    level = logging.INFO,
    stream = DelegatedStdout() # 替换原有的sys.stdout参数
)


class TestABC(unittest.TestCase):
    def test_abc_pass(self):
        logger.info('log abc in pass')
        print('print abc in pass')
        self.assertTrue(True)

    def test_abc_fail(self):
        logger.info('log abc in fail')
        print('print abc in fail')
        self.assertTrue(False)

修改后再次执行python -m unittest --buffer,成功用例的日志和print输出都会被抑制,仅失败用例的日志和print会随错误信息一同输出,符合预期要求。

可选方案:自定义测试基类实现日志缓存

如果不想修改全局logging配置,也可以通过重写unittest测试类的生命周期方法,自行实现日志的缓存和丢弃逻辑:

  • 在setUp方法中为logger添加一个内存缓存Handler
  • 重写tearDown方法,判断当前测试用例是否执行失败,失败则将缓存的日志输出,成功则清空缓存
    这种方案无需依赖--buffer参数,也能实现仅失败用例输出日志的效果。

内容的提问来源于stack exchange,提问作者Satyen A.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 20:39:03