断言基础:什么是断言、断言在软件测试中的角色、断言与日志的区别
大家好,我是你们的老朋友。今天咱们聊聊断言——这个在测试领域里既基础又容易被轻视的概念。
说实话,我见过不少团队,测试用例写了一堆,但断言写得稀里糊涂。结果呢?测试跑得欢,Bug漏得惨。嗯,这其实是个老问题了。
什么是断言?
断言,说白了就是一句“我赌这里是对的”。
在代码里,它是一个检查点。程序跑到这里,必须满足某个条件。不满足?那就直接炸掉,告诉你出事了。
举个例子,你写了个加法函数:
def add(a, b):
return a + b
# 断言:我赌 1+1 等于 2
assert add(1, 1) == 2, "加法算错了!"
如果结果不是2,程序会立刻抛出异常。这就是断言最朴素的用法。
核心要点:断言是一种“契约”。它声明了程序在某个时刻必须成立的条件。不成立,就是Bug。
我个人习惯把断言分成两类:
- 代码级断言:写在业务代码里,用于防御性编程。比如参数不能为空、数组索引不能越界。
- 测试级断言:写在测试用例里,用于验证预期结果。比如接口返回200、数据库记录数等于5。
你想想看,这两者虽然写法类似,但目的完全不同。代码级断言是“防自己”,测试级断言是“验别人”。
断言在软件测试中的角色
断言在测试里,扮演着“裁判”的角色。没有断言,测试用例就是一堆没有灵魂的代码。
我记得有一次,团队里有个新人写了个测试:
def test_login():
response = login("admin", "123456")
print(response.status_code) # 只打印,不检查
他跑完测试,看到控制台输出了200,就高兴地说“通过了”。结果第二天线上用户登录失败,排查了半天才发现——测试代码根本没断言!
你看,这就是典型的“假通过”。断言的作用,就是杜绝这种自欺欺人。
具体来说,断言在测试中承担这几个角色:
- 验证正确性:确认实际结果与预期一致。这是最基础的功能。
- 定位问题:断言失败时,能精确告诉你“哪一步”出了问题。而不是让你从头查日志。
- 文档化:好的断言本身就是一份可执行的文档。新人看断言,就能理解业务逻辑。
- 回归保障:修改代码后,断言能快速告诉你“有没有改坏东西”。
我的建议:每个测试用例至少要有1个断言。核心流程的测试,断言数量建议在3-5个。太少容易漏检,太多又显得冗余。
我曾经在一个支付项目里,因为少写了一个断言,导致金额计算错误上线了三天才被发现。那三天里,公司亏了十几万。嗯,从那以后,我再也不敢在断言上偷懒了。
断言与日志的区别
这个问题,我面试时经常问。很多人答不上来,或者答得模棱两可。
其实很简单:断言是“主动检查”,日志是“被动记录”。
咱们用一张图来理解:
咱们再细化一下区别:
| 对比维度 | 断言 | 日志 |
|---|---|---|
| 目的 | 验证条件,发现即报错 | 记录信息,供后续分析 |
| 执行影响 | 失败时中断程序 | 不影响程序执行 |
| 使用场景 | 测试、调试、防御性编程 | 生产环境监控、问题排查 |
| 信息量 | 通常只包含条件表达式 | 包含时间、级别、上下文等 |
| 性能开销 | 低(但生产环境常关闭) | 中到高(取决于日志级别) |
| 典型写法 | assert x == 1 |
logger.info("x = %d", x) |
注意:千万不要用日志代替断言!我见过有人这么写:
if result != expected:
logger.error("结果不对") # 然后继续执行
这种做法,测试会继续跑,但错误被淹没了。等你看日志时,可能已经过了好几个步骤,根本不知道哪里出的问题。
那什么时候该用断言,什么时候该用日志呢?
- 用断言:测试用例里验证结果、代码里检查前置条件、调试时确认中间状态。
- 用日志:记录请求参数、跟踪执行流程、收集性能数据、排查生产问题。
说白了,断言是“硬检查”,日志是“软记录”。两者各司其职,不能混为一谈。
一个小技巧:在测试用例里,我习惯先写断言,再写日志。断言保证正确性,日志辅助排查。顺序别搞反了——先断言,后日志。
好了,这一章的内容就到这里。断言这东西,看似简单,但用好了能省你大量排查时间。下一章咱们聊聊断言的具体写法,包括各种断言库的使用技巧。
可可精品资料库