你:“支付按钮连点5下,用户被扣了3次钱。”
开发:“需求文档写的是‘点击按钮发起支付’,没写连点啊。”
你:???
每个测试工程师都经历过这样的场景:你提了个Bug,开发轻飘飘回一句“文档里没写”,然后三方拉群、会议battle、最后不了了之。
这篇文章,帮你把这仗打赢。
一、先说结论:Bug到底怎么定义
Bug(软件缺陷),指软件中任何不符合预期行为的问题。满足以下任一条件,即可认定为Bug:
- 与需求不符—— 程序行为和需求文档、设计文档不一致
- 与合理预期不符—— 普通用户不需要懂技术,也知道“这不对劲”
- 规格有遗漏—— 文档没写,但按行业惯例和常识判断,这个行为是错的
注意第三条——这就是无数争端的根源,也是本文的重点。
文档只覆盖了“明示需求”,但Bug的判定边界还覆盖“隐式需求”。
二、别小看“文档没写”:那些天价的隐式Bug
觉得“没写就不算”是小事?历史上几大翻车现场,全是“文档没写”的场景:
- Ariane 5火箭爆炸(1996):新火箭沿用了旧火箭的代码,没人写过“新环境下数值可能溢出”这条需求。64位浮点数塞进16位整数,升空37秒后爆炸,损失数亿美元。
- Knight Capital(2012):部署遗漏导致旧代码被意外激活,45分钟亏损4.4亿美元,这家老牌金融公司直接濒临倒闭。
- 电商超卖:并发下单没做库存一致性校验,秒杀活动库存扣成负数,强制砍单引发公关灾难。
看出规律了吗?炸掉项目甚至公司的,往往不是文档里的功能,而是没人想到要写的场景。
三、核心战场:文档没写的,怎么判定?
没有文档,不代表没有标准。核心逻辑一句话:
程序在正常使用场景下,是否合理稳定、是否符合用户合理预期、是否符合行业惯例与安全底线。
3.1 五维判断表(建议收藏)
| 判断维度 | 倾向于是 Bug | 倾向于不是 Bug | 典型案例 |
|---|---|---|---|
| 行业惯例 | 与同类产品或平台规范明显相悖 | 是有意的差异化设计且已说明 | 所有App点“返回”都回上一级,你的直接闪退 |
| 用户合理预期 | 正常用户认为“理所当然该这样”却没实现 | 需要专业知识才能预期 | 百项下拉框没搜索筛选,让用户硬翻 |
| 自身一致性 | 同一功能在不同入口/环境表现不一致 | 行为一致且符合定位 | 同一按钮在A页能点、在B页没反应 |
| 历史版本对照 | 老版本正常,新版本退化 | 产品已明确公告变更 | 上个版本能导出PDF,这版突然导不了 |
| 健壮性与安全底线 | 极端输入/并发下崩溃、丢数据、越权 | 第三方系统故障且不可控 | 输入emoji就崩溃、特殊字符导致SQL报错 |
3.2 实操五步走
- 先复现,排除环境因素—— 确认不是误操作、网络抖动或第三方故障,问题能稳定重现
- 查行业惯例—— 看同类成熟产品、平台规范(Apple HIG、Material Design)怎么处理
- 找一致性参照—— 对比自身其他模块、上一版本、其他平台
- 评估用户感知—— 换位成不懂技术的普通用户,会不会困惑、误操作、丢数据
- 评估影响后果—— 涉及资金、数据、安全、崩溃等“硬红线”,直接一票认定为Bug
3.3 一套“投票口诀”
评审吵架时,心里默念这个投票机制:
- 💰硬红线(钱、数据、安全、崩溃)——一票通过,直接定Bug
- 👥用户预期 + 行业惯例—— 两票确认
- 🔍一致性对照—— 佐证材料,锦上添花
四、实战还原:三个经典Battle现场
🔥 现场一:连点下单
测试:“支付按钮连点5下,用户被扣了3次钱。”
开发:“用户自己手抖连点,这不算吧?”
测试反击:
① 主流电商App的支付按钮点击后都置灰或转loading——行业惯例;
② 重复扣款是资金问题——硬红线;
③ 防重复提交本来就是“下单功能”的一部分——隐式需求。✅判定:P0级Bug
🔥 现场二:来电中断支付
测试:“用户人脸支付时来电话,接完回来App白屏,钱扣了订单没生成。”
开发:“文档没写‘来电中断’这个场景。”
测试反击:
① 真实世界不是实验室——付款时来电话、弹推送、切出去回微信,是高频日常场景;
② 主流App都有中断恢复机制——行业惯例;
③ “扣款成功但订单丢失”——数据一致性硬红线。✅判定:P0/P1级Bug。中断测试是移动端标配,不是可选项。
🔥 现场三:跨零点边界
测试:“23:59:59下单,支付成功时已过零点,过期优惠券还被使用了,财务对不上账。”
开发:“谁半夜59秒下单?极端case。”
测试反击:
① 双11零点,几百万用户蹲点59秒下单——这不是极端case,是峰值场景;
② 账务不一致——硬红线。✅判定:Bug,且大促前必须修复。
五、十大“文档没写也要测”重灾区清单
这是隐式Bug最爱出没的地方,建议直接存成测试用例检查单:
| # | 场景 | 典型翻车现场 |
|---|---|---|
| 1 | 连点/双击 | 提交按钮没防重,一秒生成3个订单、抽奖多发3份奖品 |
| 2 | 中断场景 | 来电、弹通知、切后台被杀、锁屏、低电量关机——支付中断后订单状态错乱 |
| 3 | 弱网/断网/网络切换 | 电梯里、地铁过隧道、WiFi切4G——弱网下重复请求、超时后页面数据和实际不一致 |
| 4 | 时间边界 | 23:59:59、闰年2月29日、手动改手机时间——会员提前过期、签到奖励重复领 |
| 5 | 并发/多端 | 两台手机同时登录、网页和App同时改购物车——数据互相覆盖、库存扣负 |
| 6 | 输入法与特殊字符 | emoji昵称导致个人页崩溃(真实高发案例:数据库utf8存不了4字节emoji)、粘贴10万字、空白字符绕过校验 |
| 7 | 权限拒绝之后 | 拒绝相机/定位权限后直接闪退,而不是友好引导去设置 |
| 8 | 深色模式/横竖屏/折叠屏 | 深色模式白字白底、横屏后按钮消失、折叠屏展开布局错乱 |
| 9 | 数据量极端 | 0条数据没有空状态提示、1万条列表滑动卡死、缓存占满后功能失效 |
| 10 | 版本升级/数据迁移 | 老版本升级后本地数据丢失、历史订单打不开 |
| 每一条都有两个共同点:文档几乎不会写;出了事全是P0。 |
六、反方向提醒:这些别乱提Bug
判定标准是双向的,提单前先过一遍:
- 个人习惯 ≠ 合理预期:用户希望按钮放左边,但全行业都放右边 → 这是需求建议,不是Bug
- 极端刁钻输入 ≠ 健壮性缺陷:正常人根本不会构造的输入导致异常,可酌情降级;但涉及安全(注入、越权)必须算
- “就是这样设计的” ≠ 有效澄清:开发一句“故意的”不能闭单,需产品确认并留档
- 第三方故障 ≠ 本程序Bug:支付网关挂了不是你的锅,但缺少友好的失败提示和降级逻辑,这部分仍然是Bug
回到开头那个场景。下次再有人说“文档没写就不算Bug”,你可以把这篇文章甩过去,然后补一句:
“文档没写 = 不是Bug”,是唯文档论的单边结论。用户合理预期、行业惯例、稳定性底线,都是需求的组成部分——它们只是没被写下来而已。
当然,实战中最好的做法永远是:有分歧时拉上测试、开发、产品三方评审,用标准说话,而不是用嗓门说话。
送大家一句口诀收尾:
用户没骂过,不代表没问题;文档没写过,不代表不需要。
毕竟,我们的目标从来不是“谁赢”,而是——别让Ariane 5的故事,在你的项目里重演。
如果这篇文章帮你赢下过一次评审battle,欢迎点赞收藏。也欢迎在评论区分享你遇到过的最离谱的“这不是Bug”现场。