pytest单元测试未捕获预期抛出异常问题排查
问题根因
异常无法被捕获的核心原因是fetch_entity_from_green函数中的裸try...except Exception块吞掉了所有异常:handle_non_200_response_for_invalid_opgaver抛出的异常被外层try块捕获后,仅执行了print打印日志的操作,没有将异常重新向上抛出,函数执行完打印逻辑后会正常退出,根本不会有异常传到测试用例的pytest.raises上下文管理器中,自然无法触发预期的异常捕获。
你之前能跑通的test_handle_non_200_response用例,是直接调用异常抛出函数,外层没有包裹会吞异常的try-except逻辑,所以异常可以正常抛出被捕获,这就是两个用例表现不一致的原因。
修复方法
二选一即可:
- 方法1:删除
fetch_entity_from_green中多余的裸try-except块,让异常自然向上传递 - 方法2:如果需要保留请求异常的日志打印逻辑,在except块的print语句后加
raise关键字,将捕获到的异常重新抛出,修改后的代码片段如下:
def fetch_entity_from_green(opgave_or_sag_id, url, auth, tx): try: ENTITY = os.environ["ENTITY"] url_with_id = url + str(opgave_or_sag_id) s = fetch_request_session_with_retries() r = s.get(url_with_id, auth=auth) handle_non_200_response_for_invalid_opgaver(r, opgave_or_sag_id, ENTITY) # 其余业务逻辑 except Exception as e: print(f"An exception occured on request with id {opgave_or_sag_id}: {e}") raise # 新增这行,重新抛出异常
额外注意事项
- 修复异常抛出逻辑后,你当前测试的异常文本断言也会失败:你在
MockResponseGet410中定义的text属性值是the opgave has status: INVALID, it's gone now.,但断言里写的Error部分是Invalid opgave,和实际拼接出的异常信息不一致,需要对齐两边的文本。 - 不建议使用裸
except Exception捕获所有类型异常,这种写法会把代码语法错误、参数错误等非预期bug也一并吞掉,后续建议定义专门的业务异常类型,只捕获你需要处理的特定异常。
内容的提问来源于stack exchange,提问作者Shane Rich
相关产品推荐
相关产品推荐

