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

Python 3中用pytest测试链式自定义异常时测试失败求助

这种情况我之前在项目里也碰到过好几次,尤其是自定义异常在多层调用里抛出时,pytest偶尔会因为断言方式、异常定义或者代码里的捕获逻辑没检测到我们期望的顶层异常。结合你的环境(Python3.6 + pytest3.0.7),给你几个常见的排查方向和解决办法:

1. 检查异常断言的方式是否规范

pytest检测异常的标准姿势是用pytest.raises上下文管理器,如果你用了手动try-except的断言方式,很容易出现误判或者漏检的情况。

比如这种写法就不太靠谱:

def test_custom_exception():
    try:
        run_my_code()
    except MyCustomError:
        assert True

如果run_my_code()抛出了其他异常,这个测试也会通过,而且pytest无法准确追踪到你期望的异常。

换成标准写法试试:

def test_custom_exception():
    with pytest.raises(MyCustomError) as excinfo:
        run_my_code()
    # 还可以额外验证异常信息是否符合预期
    assert "你预期的错误提示文本" in str(excinfo.value)
2. 确认自定义异常的继承关系正确

如果你的自定义异常没有继承Python标准的Exception类(或者它的子类),pytest可能无法正确识别它是一个可捕获的异常类型。

错误的定义示例:

class MyCustomError:  # 没有继承Exception,只是普通类
    pass

正确的定义应该是:

class MyCustomError(Exception):
    pass
3. 排查业务代码中的高层级异常捕获

如果你的业务代码里有一个顶层的try-except块,把自定义异常捕获后只做了处理(比如打印日志)但没有重新抛出,那pytest自然检测不到这个异常。

比如这种情况:

def main():
    try:
        do_operation()  # 这里会抛出MyCustomError
    except MyCustomError as e:
        print(f"发生错误:{e}")  # 只打印,没重新抛出

如果你测试时调用的是main(),pytest看不到MyCustomError,因为已经被捕获消化了。解决办法要么在捕获后重新抛出(raise e),要么调整测试的调用层级,直接调用do_operation()来测试异常。

4. 考虑pytest版本的兼容性问题

你用的pytest3.0.7是2017年的老版本,虽然和Python3.6兼容,但可能存在一些异常检测的小bug。可以尝试升级到Python3.6支持的较新版本pytest(比如pytest5.3.5,这是Python3.6能支持的最高pytest版本),看看是否能解决问题:

pip install pytest==5.3.5
5. 确认测试函数的命名符合规则

pytest默认只会执行命名以test_开头的函数和类,如果你的测试函数命名不符合这个规则(比如叫my_exception_test),可能根本没被执行,导致你误以为测试失败。

如果以上方法都没解决问题,建议你把自定义异常的代码、业务代码中抛出异常的部分以及测试代码贴出来,这样可以更精准地定位问题~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 06:42:59