Pytest如何捕获指定测试用例生成的日志并在测试结束后获取存储
pytest指定测试用例日志捕获与获取方案
以下是三种主流实现方式,可根据你的日志输出场景选择:
方法1:使用capsys/capfd fixture捕获stdout/stderr输出的日志
- 适用场景:日志直接打印到标准输出/错误流的场景
- 操作方式:在测试用例参数中引入
capsys或capfdfixture,测试运行结束后调用readouterr()方法获取输出内容
示例代码:
def test_target_case(capsys): # 测试逻辑执行,过程中产生日志打印 run_your_test_logic() # 测试执行完成后捕获所有输出 captured = capsys.readouterr() # stdout输出存在captured.out,stderr输出存在captured.err case_log = captured.out # 自定义存储逻辑 with open("target_case.log", "w", encoding="utf-8") as f: f.write(case_log)
capfd和capsys的区别是前者可捕获文件描述符级别的输出,适配更多第三方日志库的打印场景
方法2:使用caplog fixture捕获logging模块输出的日志
- 适用场景:日志通过Python标准库
logging模块输出的场景,是最常用的日志捕获方案 - 操作方式:在测试用例参数中引入
caplogfixture,直接访问其属性获取所有日志记录
示例代码:
import logging import pytest @pytest.mark.your_target_mark def test_target_case(caplog): # 可设置捕获的最低日志级别,也可指定只捕获特定模块的日志 caplog.set_level(logging.INFO, logger="your_business_module") # 测试逻辑执行,过程中通过logging输出日志 run_your_test_logic() # 获取结构化日志记录(每条为logging.LogRecord对象) all_log_records = caplog.records # 获取已格式化的纯文本日志内容 log_text = caplog.text # 自定义存储逻辑 with open("target_case.log", "w", encoding="utf-8") as f: f.write(log_text)
方法3:自定义pytest hook实现指定用例日志自动持久化
- 适用场景:需要批量捕获指定标记用例的日志、统一管理日志存储路径与格式的场景
- 操作方式:在
conftest.py中实现pytest运行钩子,测试用例前后动态添加/移除专属日志处理器
示例代码:
import logging from pathlib import Path import pytest @pytest.hookimpl(tryfirst=True) def pytest_runtest_setup(item): # 只给打了capture_log标记的指定用例添加日志处理器 if not item.get_closest_marker("capture_log"): return # 生成用例专属日志路径 case_name = item.name log_path = Path("./test_logs") / f"{case_name}.log" log_path.parent.mkdir(exist_ok=True) # 自定义日志格式与处理器 handler = logging.FileHandler(log_path, encoding="utf-8") formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") handler.setFormatter(formatter) # 挂载处理器到根日志器 logging.getLogger().addHandler(handler) # 把处理器存在用例对象上,后续清理用 item.case_log_handler = handler @pytest.hookimpl(trylast=True) def pytest_runtest_teardown(item): # 测试用例结束后移除处理器,避免日志重复输出 if hasattr(item, "case_log_handler"): logging.getLogger().removeHandler(item.case_log_handler) item.case_log_handler.close()
测试运行结束后,所有带@pytest.mark.capture_log标记的指定用例日志都会自动存储在./test_logs目录下,以用例名命名
内容的提问来源于stack exchange,提问作者username
相关产品推荐
相关产品推荐

