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

如何用pytest raises同时验证异常处理逻辑及日志输出

解决方法

问题出在测试里没mock my_operation函数,导致调用真实的my_operation时,异常直接中断了流程,没触发my_function里的异常处理逻辑。下面是具体的解决步骤:

1. 修正原代码的方法定义(可选但符合规范)

原MyClass.my_function用了cls当参数,却没加@classmethod装饰器,实例调用时会把实例对象传给cls,虽然不影响异常处理,但不符合Python编码规范,建议调整:

from some_other_module import my_operation
import logging

class MyClass:
    def my_function(self):  # 实例方法用self
        try:
           my_operation()
        except Exception as exc:
           logging.info("something went wrong")
           raise
        # 如果是类方法,需添加装饰器:
        # @classmethod
        # def my_function(cls):
        #     try:
        #        my_operation()
        #     except Exception as exc:
        #        logging.info("something went wrong")
        #        raise

2. 编写正确的pytest测试用例

用unittest.mock.patch来mockmy_operation,让它抛出可控异常;再用pytest自带的caplog捕获日志,同时验证异常是否被重新抛出:

import pytest
import logging
from unittest.mock import patch
from your_module import MyClass  # 替换为原代码所在的模块名

def test_my_function(caplog):
    # 设置日志捕获级别为INFO,确保能抓到目标日志
    caplog.set_level(logging.INFO)
    
    # mock my_operation,让它抛出指定异常
    with patch('your_module.my_operation') as mock_op:
        mock_op.side_effect = Exception("测试用异常")
        
        obj = MyClass()
        # 验证异常被重新抛出
        with pytest.raises(Exception):
            obj.my_function()
    
    # 检查日志是否正确输出
    assert "something went wrong" in caplog.text
    # 可选:确认mock函数确实被调用过一次
    mock_op.assert_called_once()

关键点说明

  • mock my_operation:通过patch替换真实函数,让它在测试中抛出我们指定的异常,确保my_function内的try-except逻辑被触发,而非调用真实函数导致流程直接中断。
  • caplog fixture:pytest内置工具,专门用于捕获日志输出,方便验证日志内容是否符合预期。
  • pytest.raises:捕获重新抛出的异常,确保整个异常处理流程完整——捕获异常、打印日志、重新抛出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:34:56