3. 测试计划制定:从策略到风险,一个都不能少

测试计划这东西,说白了就是整个验证工程的作战地图。我见过不少团队,一上来就闷头写用例,写到一半发现方向偏了,回头再改,那叫一个痛苦。所以,在动笔之前,先把策略、方法、目标和风险这四件事想清楚,后面才能走得顺。

3.1 测试策略:先打哪,怎么打?

测试策略解决的是「打什么」和「怎么打」的问题。GEM 标准功能集成测试,我们面对的不再是单个模块,而是多个模块拼在一起后的交互。我个人习惯把策略分成三个层次:

  • 冒烟测试(Smoke Test):先跑通最核心的几条通路。比如,配置寄存器、发起一次标准读/写事务、检查中断是否正常。这层不过,后面的都不用看了。
  • 功能覆盖测试(Functional Coverage):针对协议规定的所有合法场景,逐一验证。这层是主体,工作量最大。
  • 压力与边界测试(Stress & Corner):把总线灌满、把 FIFO 压到溢出、把时序推到最紧。很多 bug 藏在这里。

我的经验: 冒烟测试的用例一定要精,不要超过 10 条。我在一个项目里见过有人写了 50 条冒烟用例,结果跑一次要半小时,那还叫冒烟吗?那是马拉松。

3.2 测试用例设计方法:别只盯着一种套路

设计用例的方法很多,但别死磕一种。我常用的组合拳是这样的:

方法 适用场景 个人心得
等价类划分 地址范围、数据长度、命令类型 把无限输入变成有限类,省时省力
边界值分析 FIFO 深度、计数器溢出、时序窗口 80% 的 bug 在边界上,别偷懒
状态机遍历 协议状态跳转、仲裁逻辑 画个状态图,然后每个箭头都走一遍
随机约束 大规模回归测试 配合覆盖率反馈,否则就是瞎跑
错误注入 异常处理、超时、重试机制 我曾经漏掉一个超时场景,结果芯片在客户现场死锁了……

你想想看,如果只用随机约束,没有边界值分析,那 FIFO 满的时候到底能不能正确处理?随机很难恰好踩到那个点。所以,定向用例 + 随机约束才是王道。

3.3 覆盖率目标定义:没有目标,就是瞎忙

覆盖率不是越高越好,而是够用就好。但「够用」怎么定义?我一般这样定:

  • 代码覆盖率:行覆盖 ≥ 90%,条件覆盖 ≥ 85%,状态机覆盖 ≥ 95%。低于这个数,说明有代码没跑到。
  • 功能覆盖率:协议规定的所有合法场景必须 100%。注意,是「必须」。非法场景可以放宽到 80%,因为有些非法组合确实没必要全测。
  • 断言覆盖率:所有写过的断言,必须被触发至少一次。如果断言从来没被触发过,要么是断言写错了,要么是场景没覆盖到。

注意: 别盲目追求 100% 代码覆盖率。我见过一个项目,为了凑覆盖率,把一些根本不会执行的死代码也测了,纯属浪费时间。覆盖率是工具,不是目的。

3.4 风险评估:提前想好「万一」

做计划的时候,最容易被忽略的就是风险。我习惯在计划里单独列一节「风险与缓解措施」。常见的风险有:

  • 环境风险:仿真环境搭建慢、EDA 工具 license 不够。缓解:提前申请资源,准备备用方案。
  • 设计风险:RTL 交付延迟、接口变更频繁。缓解:和设计团队建立周会机制,及时同步。
  • 验证风险:用例复杂度高、回归时间太长。缓解:分层验证,把慢的用例放到 nightly 跑。

嗯,这里要注意,风险评估不是写给别人看的,是给自己用的。我曾经在一个项目里,因为没评估好回归时间,结果 tapeout 前一周还有一半用例没跑完,那叫一个慌。从那以后,我每个 milestone 都会重新审视风险列表。

3.5 知识体系总览

下面这张图,把测试计划的四个核心模块串起来了。你可以把它贴在工位旁边,写计划的时候对照着看。

测试计划制定 - 核心知识体系 测试计划 测试策略 用例设计方法 覆盖率目标 风险评估 冒烟测试 功能覆盖测试 压力与边界测试 等价类划分 边界值分析 随机约束 + 错误注入 代码覆盖率 功能覆盖率 断言覆盖率 环境风险 设计风险 验证风险 核心原则:策略定方向,方法保覆盖,目标可衡量,风险有预案

小技巧: 写测试计划的时候,可以先用思维导图把上面四个模块展开,然后再填充细节。这样结构清晰,不容易漏项。