TT Lab
开始
学习 学习路径 课程

面对陌生系统

先做判定器,再开始缩小

在 TT Lab 中继续学习

一句话总结

构建最小复现用例,有一半的工作不是精简技巧,而是让机器来判定“是否仍然是同一个失败”。没有判定器,精简就成了猜测。

为什么需要它

客户发来的复现步骤,通常就是那个人当天做过的全部事情:附带一份 12 步的步骤和一份 200 行的输入文件。带着这一切去找原因,需要查看的组合会爆炸,你会从随便哪个地方开始,两天之后仍然停在原地。

大家都知道要精简,问题是精简着精简着就迷了路。删掉一行,程序因为另一个错误崩溃了。另一个错误也是错误,于是误以为“仍然能复现”,继续精简。这样得到的三行输入,复现的是与我们要找的缺陷毫无关系的另一个缺陷。拿着这三行去找客户的开发团队,一天就白白浪费了。

为什么判定器要先做

所以有一个顺序:精简之前先做判定器。判定器(oracle)是这样一个程序:接收一个候选输入,只回答“它现在是否产生了我们在追查的那个失败”。靠人眼来判断,无法用于精简。精简要把候选试上几十到几百次,而这个次数人是承受不了的。

判定器要看的大致有三样。

反过来,也有判定器不该看的东西。运行时间、临时文件名、日志行数这类每次运行都会变的内容,不要放进判定。放进去的话,同一个候选有的日子能复现,有的日子不能。

工作原理

有了判定器,精简就由机器来做。最简单的办法是一行一行地删。200 行就调用 200 次判定器,每走完一遍剩下的行数减少,于是又要再走一圈。结果是对的,但很慢。

Zeller 和 Hildebrandt 的 ddmin则以块为单位来做。把候选分成 n 片,先看只用其中一片能不能复现,不行的话再看去掉一片后的其余部分能不能复现。两种都不行,就切得更细,重复同样的事。如果起作用的只有两行,调用次数会降到接近行数的对数:在 256 行中找出两行,只需要调用一百次出头的判定器。

[a b c d e f g h]        전체가 재현된다
  갈라 본다 → [a b c d] [e f g h]
  [a b c d] 재현 안 됨
  [e f g h] 재현 안 됨          ← 조각 하나만으로는 안 된다
  나머지로 본다 → [e f g h](= a b c d 를 뺀 것) 안 됨, [a b c d] 안 됨
  더 잘게 → [a b] [c d] [e f] [g h]
  [a b] 뺀 나머지 재현됨 → 후보가 [c d e f g h] 로 줄었다
  … 반복 …
결과: [c g]  — 여기서 c 나 g 를 빼면 재현되지 않는다

该代码块中的韩文依次说明:整体可以复现;分成两半来看,只用其中一半都无法复现,也就是单独一片不行;再看去掉一半后的其余部分,也都不行;切得更细,去掉 [a b] 后的其余部分可以复现,候选缩小为 [c d e f g h];重复这个过程;最终结果是 [c g],从中去掉 c 或 g 都无法复现。

结果是 1-最小(1-minimal),意思是剩下的内容中去掉任何一个,复现就会停止。这并不意味着“最小”:也许还存在完全不同的更小的组合。所以精简结束之后,要把剩下的每一行逐个去掉并确认复现停止,并且单独写下这份证明。没有这份证明,就回答不了“为什么需要这一行”这个问题。

在现场相遇的样子

第一,步骤也要像输入一样精简。12 步中实际需要的只有四步,这种情况很常见。其余八步是负责人的习惯。精简了步骤,“怪环境”这种含糊的解释就消失了。

第二,在干净的地方运行。如果前一次运行留下了文件,即使去掉“创建配置文件的步骤”也能复现,于是会得出“这一步不需要”的错误结论。每次试验步骤时,都要新建一个空目录。

第三,改变取值来确认精简出的用例是不是真的。如果剩下的两行是 locale=de 和 qty=1,5,就看把数字改成 9,25 之后是否仍能复现。能复现的话,原因就不在那个数字上,而在于逗号和区域设置(locale)的组合。做到这一步,才成为客户开发团队可以立刻修复的报告。

第四,最小用例要连同判定器一起发送。只发两行输入,接收方会先问“这为什么是个问题”。连同判定器一起发送,接收方在自己那里运行一次,就会立刻站到同一个位置上。

实际工作中真正重要的事

下一项实验要做什么

展开(虚构的)Daerim 物产发来的故障包:一个处理程序、200 行的 feed,以及 12 步的复现步骤。先做出判定“同一个失败”的判定器,用它来精简 feed,再把剩下的每一行逐个去掉,证明结果是 1-最小。接着亲自实现 ddmin,把精简自动化:评分器会在每次把答案藏在不同位置的 256 行输入上运行你的缩减程序,同时查看结果是否正确,以及调用了多少次判定器。最后精简 12 步的复现步骤,确认改变取值后是否仍能复现,并写成报告提交。