pytest测试异常抛出不符合预期,无法执行断言求助
核心问题排查
你的测试断言没执行,并非是抛出异常导致流程终止——pytest.raises上下文管理器本身就是用来捕获预期异常的,只要异常被成功捕获,后续断言一定会执行。真正的问题是代码或测试存在隐性错误,导致测试在断言前就失败了,常见原因及修复方案如下:
1. CustomError未携带状态码,断言触发AttributeError
原函数抛出异常时没有传递响应状态码:
raise CustomError() # 未传入status_code参数
而测试里断言error.value.code == 500,如果CustomError类没预设code属性,或者初始化时没接收并保存状态码,这里会直接抛出AttributeError,看起来像是测试终止了。
修复步骤:
- 先修改
CustomError的定义,支持接收并存储状态码:class CustomError(Exception): def __init__(self, code): self.code = code super().__init__(f"请求失败,状态码:{code}") - 再修改原函数的抛出逻辑,传入响应状态码:
if response.status_code != 200: raise CustomError(response.status_code) # 把状态码传给异常类
2. Requests的Mock路径不正确
如果mocker.patch("path.to.file.requests")里的路径错误,实际的requests.put没有被Mock,会发送真实请求,可能抛出网络错误或其他异常,导致pytest.raises(CustomError)捕获不到预期异常,测试直接失败,断言自然不会执行。
验证与修复:
在测试中添加打印,确认Mock是否生效:
def test_put_request_error(mocker): requests_mock = mocker.patch("path.to.file.requests") requests_mock.put.return_value.status_code = 500 # 调用后打印,确认Mock是否被触发 put_request(param1="test", param2={"key": "val"}) print(requests_mock.put.called)
如果打印结果为False,说明路径错误,需要改成put_request函数所在文件中import requests的实际路径。比如你的put_request在my_project/api.py里,路径应该是my_project.api.requests。
3. 测试参数未定义或语法错误
测试里调用put_request(param1=param1, param2={some data}),其中param1是未定义的变量,{some data}是非法语法,会直接触发NameError或语法错误,导致测试在进入pytest.raises上下文前就失败了。
修复方案:
传入合法的测试参数,比如:
put_request(param1="test_param", param2={"key": "test_value"})
4. CustomError未正确导入到测试文件
如果测试文件里没导入CustomError,pytest.raises(CustomError)会触发NameError,导致测试直接失败。
修复方案:
在测试文件顶部导入CustomError:
from your_module import CustomError
内容的提问来源于stack exchange,提问作者TurmoiledPython

