3. 测试用例优先级:基于历史数据的动态优先级排序算法

量产测试里有个很现实的问题:测试时间永远不够用。你想想看,一颗芯片在测试机上多待 1 秒,乘以几百万颗的产量,那就是几百个小时的机时浪费。但测少了又怕漏掉坏品。怎么办?

我的答案是:让测试用例自己学会「排队」。说白了,就是根据历史数据,把最容易抓到坏品的用例排到前面,把那些万年不挂的用例往后放。这就是动态优先级排序的核心思路。

核心观点: 测试用例优先级不是拍脑袋定的,而是从历史测试数据里「长」出来的。每次测试都在为下一次排序提供依据。

3.1 为什么需要动态优先级?

静态优先级你肯定见过——就是工程师凭经验给每个用例打个分,然后一直用下去。我在项目初期也这么干过,但很快就发现问题了。

举个例子:某个用例在工程验证阶段特别能抓 bug,但到了量产阶段,工艺稳定了,它可能连续几万颗都不挂一次。这时候它还排在前面,就是在浪费机时。反过来,有些用例在初期表现平平,但随着工艺老化或批次变化,突然变得很敏感。静态方案根本跟不上这种变化。

动态优先级要解决的就是这个问题:

  • 适应工艺漂移 — 同一个用例在不同批次的有效性可能天差地别
  • 缩短平均测试时间 — 让高收益用例先跑,尽早触发 fail,提前终止
  • 自动淘汰冗余 — 长期不挂的用例自动降权,把时间让给更有效的用例

我的经验: 有一次某个产品线突然良率波动,静态优先级方案下我们花了三天才定位到是某个低频用例失效了。换成动态方案后,第二天系统就自动把这个用例的权重拉高了。这就是数据驱动的价值。

3.2 算法核心:基于贝叶斯更新的优先级计算

我习惯用贝叶斯方法来做这件事。为什么?因为它天然适合「用新数据不断修正旧认知」的场景。

简单说,每个用例都有一个「抓错概率」P(fail | run)。初始值可以用工程验证阶段的数据来设。每跑一批芯片,我们就用实际结果来更新这个概率。

公式其实不复杂:

P_new = (P_prior * N_prior + actual_fails) / (N_prior + N_new)

其中:

  • P_prior — 之前的抓错概率
  • N_prior — 之前的总运行次数(等效样本量)
  • actual_fails — 本轮实际抓到的 fail 数量
  • N_new — 本轮运行次数

每次测试完,这个概率都会微调。概率高的用例,下次优先跑。

注意: 初始值不要设成 0。如果某个用例从来没挂过,P_prior 可以设一个很小的非零值(比如 0.001),否则它永远没机会被选中,也就永远无法发现它是否变敏感了。

3.3 排序策略:不只是概率

光看抓错概率还不够。你想想看,一个用例跑一次要 500ms,另一个只要 5ms,就算前者概率高一点,也不一定划算。

所以我一般会引入一个「性价比」指标:

priority_score = P(fail) / test_time * weight_history

这里 weight_history 是一个衰减因子,防止某个用例因为历史表现太好而永远霸占前排。我通常设一个半衰期——比如每 10000 次测试,历史权重衰减一半。

排序时,按 priority_score 从高到低排列。测试机按这个顺序执行,一旦遇到 fail,就可以提前终止当前芯片的测试,进入下一颗。

用例 ID 抓错概率 测试时间 (ms) 性价比得分 排序位置
TC_001 0.023 50 0.00046 1
TC_002 0.001 5 0.00020 2
TC_003 0.015 200 0.000075 3
TC_004 0.0005 10 0.00005 4

你看,TC_002 虽然抓错概率低,但因为跑得快,性价比反而排到了第二。这就是把时间花在刀刃上。

3.4 算法流程与系统架构

整个流程我画了一张图,方便你理解数据是怎么流转的:

动态优先级排序算法流程图 动态优先级排序算法流程 历史测试数据库 贝叶斯概率更新模块 性价比得分计算 动态排序引擎 测试机执行(按序) 测试结果回写 检测到 Fail → 终止 每次测试完成后,结果自动回写数据库,触发下一轮的贝叶斯更新

这个架构里有个关键点:反馈回路。测试结果必须实时回写,不能等 batch 跑完再统一更新。否则排序永远滞后。

3.5 工程落地要点

算法听起来不错,但落地时坑不少。我踩过几个,跟你分享一下:

  • 冷启动问题 — 新用例没有历史数据怎么办?我习惯先用工程验证数据做初始训练,或者给一个保守的默认值。
  • 数据倾斜 — 如果某个批次全是良品,会导致所有用例的概率一起下降。这时候要引入批次归一化,消除批次间的系统性偏差。
  • 计算开销 — 每次测试完都重新排序?不现实。我一般设一个更新周期,比如每 1000 颗或每 10 分钟重新计算一次。

我曾经踩过的坑: 有一次忘了处理「用例从未被执行」的情况。结果某个新加的用例优先级一直是 0,永远排不上队。后来加了一个强制轮询机制——每个用例至少每 N 次测试必须被执行一次,不管它的优先级多低。

3.6 效果评估指标

怎么知道动态优先级有没有用?我一般看三个指标:

指标 定义 目标
平均测试时间 单颗芯片的平均测试时长 降低 15% 以上
早期捕获率 前 30% 用例捕获的 fail 占比 达到 80% 以上
漏测率 被跳过用例中实际有问题的比例 低于 0.1%

我在一个项目中落地这套方案后,平均测试时间降了 22%,早期捕获率从 65% 提升到了 91%。效果很明显。

我的建议: 不要一上来就全量切换。先选一条产线做 A/B 测试,跑一周对比数据。老板看到数据后才敢让你全面推广。

动态优先级排序,说白了就是让数据替你做决策。你只需要搭好框架,定好规则,剩下的交给算法自己去迭代。这样你就有更多时间去处理真正棘手的问题——比如那些连算法都搞不定的「玄学」失效。