使用pytest捕获异常失败:测试未检测到预期抛出的异常
问题分析:pytest无法捕获预期异常的原因及修复方案
问题根源
你的测试用例失败的核心原因很明确:你的业务代码并没有真正向外抛出异常,而是把异常“吞掉”后返回了错误信息字符串。
看一下convert函数的逻辑:当检测到除数为0或者输入不是数字时,你确实先raise了异常,但紧接着在except块里直接return了对应的错误字符串。这意味着函数执行到这里就结束了,异常并没有被抛出到函数外部——而pytest的pytest.raises()是用来捕获函数向外抛出的异常,自然就抓不到任何东西,所以会提示DID NOT RAISE。
修复方案
根据你的业务需求,有两种不同的修复方向:
方向1:让函数真正抛出异常(推荐,符合常规错误处理逻辑)
如果你的业务设计是希望convert函数在遇到错误时抛出异常,让上层调用者处理,那需要修改convert函数,去掉多余的try-except块,直接在条件满足时抛出异常:
def convert(x): x = x.rpartition("/") # Partitioning a = x[0] b = x[2] if b == "0": raise ZeroDivisionError("Zero Division Error") if not a.isdigit() or not b.isdigit(): raise ValueError("Value Error") a = int(a) b = int(b) return round(a/b)
这样修改后,调用convert("a/4")时函数会直接抛出ValueError,调用convert("7/0")时抛出ZeroDivisionError,你的原有测试用例就能正常通过了。
方向2:修改测试用例,断言返回的错误字符串
如果你的业务代码必须保持返回错误字符串的逻辑(比如有其他依赖这个返回值的代码),那就要调整测试用例,不再尝试捕获异常,而是直接断言函数的返回值是否符合预期:
from Test import convert def test_convert1(): assert convert("a/4") == "Value Error" def test_convert(): assert convert("7/0") == "Zero Division Error"
这种情况下,函数不会抛出任何异常,所以pytest.raises()就不适用了,直接验证返回值即可。
总结
如果是开发库或者需要上层处理错误的场景,推荐用方向1的方案,遵循Python“请求原谅比请求许可更好”的错误处理风格;如果是简单脚本,函数设计就是返回错误信息给用户,那用方向2的方案更合适。
内容的提问来源于stack exchange,提问作者Etile
相关产品推荐
相关产品推荐

