pytest 异常断言是什么
pytest.raises 是断言异常分支的上下文管理器:with pytest.raises(ZeroDivisionError) 包住触发代码,异常类型不匹配或不抛异常都会让用例失败。match 参数按正则匹配异常消息,进一步收紧判定;as excinfo 拿到异常对象后还能断言属性、错误码等细节。只断言「抛了异常」不够——异常类型与消息同时校验,才能防止其他异常被误判为通过。
基本信息
| 基本形式 | with pytest.raises(期望类型): 触发代码 |
|---|---|
| 消息匹配 | match 参数用正则搜索异常消息(re.search 语义) |
| 对象捕获 | as excinfo 取 excinfo.value / type / traceback 继续断言 |
| 失败行为 | 类型不符与未抛异常都判失败,报错信息明确 |
| 配合场景 | 业务异常包装、参数校验、资源不可用等分支验证 |
异常断言
异常断言
import pytest
def test_divide():
with pytest.raises(ZeroDivisionError, match="division by zero"):
1 / 0
def test_value():
with pytest.raises(ValueError) as excinfo:
int("abc")
assert "invalid literal" in str(excinfo.value)
def test_custom_error_code():
with pytest.raises(BizError) as excinfo:
service.pay(-1) # 期望业务层拒绝
assert excinfo.value.code == 400 # 连错误码一起断言典型使用场景
- 参数校验:非法输入应抛出校验类异常。
- 业务规则拒绝:余额不足、权限不足等分支的错误码核对。
- 资源错误包装:底层异常被转换为带上下文的上层异常。
- SDK 行为验证:库在边界输入下的异常契约是否稳定。
- 修复回归:缺陷修复时先写异常断言,锁住分支行为。
- 文档核对:异常类型与消息是否与接口文档一致。
写法对照
| 写法 | 覆盖程度 | 说明 |
|---|---|---|
| pytest.raises(Exc) | 仅类型 | 最弱:其他同类消息也通过 |
| pytest.raises(Exc, match=...) | 类型+消息 | 推荐起步:正则搜索消息 |
| excinfo.value 属性断言 | 类型+消息+属性 | 最强:连错误码等一并核对 |
| try/except + fail | 视写法而定 | 老写法冗长,容易吞掉意外异常 |
只断言「抛了异常」时建议同时校验消息或错误码,避免其他异常被误判通过。
match 按正则解析:消息里的括号、点号、方括号等特殊字符需要转义,否则匹配规则会悄悄放水。
异常分支同样要查副作用:拒绝操作后数据库不应留下半成品记录,异常断言与状态断言配对使用。