使用pytest测试`raise X from Y`异常链有哪些可行方案?
pytest测试
raise X from Y异常链的可选实现方案 不需要侵入业务代码拼接异常消息,核心利用Python原生异常链特性:使用raise X from Y语法抛出的异常,会自动将Y赋值给X异常实例的__cause__属性,直接校验该属性即可,可选实现方式如下:
方案1:直接捕获异常上下文校验
__cause__属性
这是最常用的轻量方案,无需修改原有业务代码,测试代码示例如下:def test_class_c(): with pytest.raises(ValueError) as exc_info: C() # 校验源异常类型符合预期 assert isinstance(exc_info.value.__cause__, AException) # 校验源异常的消息内容符合预期 assert str(exc_info.value.__cause__) == "Class A"该方案优势:完全不侵入业务逻辑,校验维度更精准,不会因为业务侧调整异常消息格式导致测试误判。
方案2:封装公共校验函数复用逻辑
如果项目中存在大量异常链校验场景,可以将校验逻辑封装为公共工具函数,降低测试代码重复率:# 公共校验工具 def assert_exception_cause(exc_instance, expected_cause_type, expected_cause_msg=None): assert isinstance(exc_instance.__cause__, expected_cause_type) if expected_cause_msg is not None: assert str(exc_instance.__cause__) == expected_cause_msg # 测试用例 def test_class_c(): with pytest.raises(ValueError) as exc_info: C() assert_exception_cause(exc_info.value, AException, "Class A")
原有将原始异常信息拼接至新异常消息的方案存在业务逻辑和测试逻辑耦合的问题,一旦业务侧需要调整异常消息的输出格式,测试用例就需要同步修改,更推荐使用上述基于__cause__的校验方案。
内容的提问来源于stack exchange,提问作者vladsiv
相关产品推荐
相关产品推荐

