pytest中需用caplog fixture捕获logging日志(默认仅WARNING+,可用set_level调整),用capsys/capfd捕获print输出;二者独立,caplog不处理print,且日志格式影响caplog.text内容。

pytest中如何捕获print输出和logging日志?
pytest本身不自动捕获print()或logging输出,必须显式启用捕获机制。默认运行时(如pytest test.py)会抑制stdout/stderr,但不会捕获logging——后者需额外配置handler。
关键区别:
- print()属于标准输出,用-s或--capture=no可看到,但无法在测试里断言;
- logging默认输出到终端,但测试中要校验内容,得把日志重定向到内存缓冲区(比如io.StringIO或pytest内置的caplog fixture)。
用caplog fixture捕获并断言logging内容
caplog是pytest内置fixture,专为logging设计,无需手动添加handler,开箱即用。
- 它默认捕获
WARNING及以上级别日志;如需捕获INFO或DEBUG,需提前设置caplog.set_level() - 日志记录以
caplog.records列表形式存在,每个元素是LogRecord对象,可访问.message、.levelname、.name等属性 - 也可用
caplog.text获取拼接后的完整日志字符串(含级别、logger名、消息),适合简单模糊匹配
示例:
def test_log_message(caplog):
import logging
logger = logging.getLogger(__name__)
logger.info("User login failed")
assert "login failed" in caplog.text
assert len(caplog.records) == 1
assert caplog.records[0].levelname == "INFO"
为什么caplog有时捕获不到INFO或DEBUG日志?
因为caplog默认只捕获WARNING及以上级别,而root logger初始level通常是WARNING,但你的模块logger可能设了更低level(如INFO),却没生效——根源在logging配置未传播或被root handler拦截。
- 最简解法:在测试函数开头调用
caplog.set_level(logging.INFO) - 若用
logging.basicConfig()初始化过,需确保它没把level设太高,或改用caplog.set_level()覆盖 - 避免在测试外全局调用
logging.getLogger().setLevel(...),它会影响其他测试,且pytest可能已重置logger状态
想同时捕获print和logging怎么办?
不能靠caplog捕获print(),它只管logging。要断言print()输出,得用capsys或capfd fixture:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
capsys捕获sys.stdout和sys.stderr(纯文本,不含颜色/ANSI转义) -
capfd更底层,能捕获被重定向到文件描述符的输出(比如某些C扩展打印的内容) - 两者都提供
.readouterr()方法,返回namedtuple(stdout, stderr)
示例:
def test_print_and_log(capsys, caplog):
print("Hello")
import logging
logging.warning("Something went wrong")
out, err = capsys.readouterr()
assert "Hello" in out
assert "Something" in caplog.text
注意:capsys和caplog互不干扰,可共存;但别指望caplog.text里出现print()内容——那是两个完全不同的输出通道。
真正容易被忽略的是:日志格式器(Formatter)会影响caplog.text内容。如果你在代码里调用了logging.basicConfig(format="%(asctime)s - %(message)s"),那caplog.text里就会带时间戳,断言时得考虑这部分噪声。直接断言caplog.records[0].message更干净。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










