用例设计方法论:从"需求翻译"到"风险驱动"

“按需求写用例"是新人第一直觉,也是天花板最低的方法——需求文档写得越细,用例越"正确”,而 bug 恰恰藏在需求没写的地方。这篇讲用例设计的三个层次:正确性、完整性、风险优先级,以及怎么从"翻译需求"进化到"驱动风险"。

一、第一层:正确性(把需求翻译对)

最基础但最常被低估:用例先验证"需求本身",再验证"实现"

1. 需求歧义先行

写用例前过一遍需求,把所有"看起来理所当然"的假设显式化:

1
2
3
4
5
6
7
需求:"用户输入手机号注册,手机号已存在时提示'该手机号已注册'"

假设清单(逐条找开发确认):
□ "已存在"含已注销的账号吗?(业务歧义)
□ 提示是 toast 还是行内错误?(交互歧义)
□ 11 位以外(10/12 位)算"手机号"吗?(边界歧义)
□ 大小写/空格/国家区号前缀怎么处理?(输入歧义)

经验:歧义清单里 70% 的问题,开发自己也没想过——用例设计在这个阶段就是在帮开发补需求,越早暴露成本越低

2. 等价类 + 边界的标准动作

1
2
3
4
5
6
7
8
9
输入:手机号(11 位数字)
等价类:
有效:11 位数字(13x/14x/15x/16x/17x/18x/19x 各抽一)
无效-长度:10 位 / 12 位
无效-字符:含字母 / 含特殊符 / 全空格
无效-值:0 开头 / 10 开头
边界:
长度边界:10↔11↔12
值边界:13000000000(最小真实号段)/ 19999999999

等价类不是"列一堆",是每类只取代表值——11 位手机号不需要测 100 个,取号段代表 + 边界即可。用例数量失控的根源是"穷举",等价类的本质是"有依据的抽样"

二、第二层:完整性(覆盖需求之外的面)

需求没写的地方按四个通用维度补:

1. 状态维度

"提交订单"是动作,但订单有状态机。用例要覆盖状态迁移而不是孤立动作:

1
2
3
4
5
6
状态机:草稿 → 已提交 → 已支付 → 已发货 → 已完成
异常迁移:已支付 → 退款中 → 已退款
非法迁移:已发货 → 已支付(应被拒绝)

用例 = 合法迁移全覆盖 + 关键非法迁移抽测
遗漏高发区:异常态回到正常态(退款后再下单、冻结后解冻)

2. 时序维度

并发和乱序是需求永远不写的:

  • 并发:两个客户端同时改同一订单 → 谁赢?冲突提示?
  • 乱序:支付回调晚于"取消"到达 → 钱扣了单没了?
  • 超时:请求发了没响应,用户又点了一次 → 双单?
  • 重试:客户端超时重发,服务端已处理 → 幂等吗?

这四个问题每个功能都值得问一遍,问不出答案的需求,测试阶段就是排雷现场。

3. 数据维度

  • 空数据:新账号 0 订单、0 消息的页面表现;
  • 极限数据:单条超长文案(1000 字符备注)、单页 10 万条列表;
  • 脏数据:历史迁移来的异常值(负数金额、乱码昵称)。

4. 环境维度

(详见弱网/安全两篇)弱网、断网恢复、多语言、深浅色、不同分辨率、老版本兼容。

三、第三层:风险驱动(把有限用例投给最可能出事的地方)

用例永远不够用,排优先级 = 按风险排布

1
2
3
4
5
6
7
8
9
10
风险值 = 失效概率 × 失效影响

失效概率来源(历史数据):
- 该模块近 6 个月 bug 密度
- 本次改动的 blast radius(动了多少调用方)
- 新代码占比(重写 > 修改 > 无改动)

失效影响来源(业务判断):
- 资金链路 > 数据一致性 > 核心体验 > 边缘功能
- 影响用户数(全量 vs 灰度人群)

落地成用例标记 + CI 分档

1
2
3
4
5
6
7
# 每个用例标风险级(标记进用例元数据)
@critical 资金/数据一致性,失效即 P0 → 每次提交必跑
@high 核心链路,失效影响主流程 → 每日必跑
@medium 常规功能 → 发版前跑
@low 展示/文案/边缘 → 抽跑或人工

# 发版时间紧时:砍 @low 保 @critical,砍的依据是风险值不是"哪个快"

风险驱动的检验标准:一次线上事故后回看,触发事故的路径是否在 @critical/@high 里。如果事故路径跑的是 @medium 而没跑 @critical 的用例——不是漏用例,是风险评错了,更新评级模型比补一条用例重要。

四、用例资产化:设计方法的载体

设计方法再好,落在"脑子里"就等于零。载体要求:

  1. 用例结构化(标题/前置/步骤/预期/风险级/关联需求),平台可检索可统计;
  2. 需求 ↔ 用例双向可追:需求改动能查影响用例(反向 blast radius),用例能查覆盖哪条需求;
  3. 评审留痕:风险评级和"不测某路径的理由"都写进用例——"为什么没测并发"在事故复盘时是要交代的;
  4. 定期重评:风险级不是定死的,每季度按 bug 数据重排一次。

五、小结

用例设计的三层递进:正确性(假设显式化 + 等价类抽样)、完整性(状态/时序/数据/环境四维度)、风险驱动(失效概率 × 影响,用例投给最可能出事处)。从"需求翻译"到"风险驱动"的分水岭是一个问题的转变:翻译问"需求说了什么",风险驱动问"哪里会出事,出了事多疼"。