跳转至

Lecture 12. Mutation Testing 变异测试

(睡过了)

变异测试是,故意把一些错误的代码插入到源程序当中(一次插入一个错),然后用之前学过的测试方法进行测试。正常情况下,运行结果应当是错误的。

通常修改的东西都是:大于号故意改成小于号啦,等于号故意改成不等于啦,边界故意取不取啦~

变异运算符 Mutation Operators

变异运算符是派生编译的规则。说人话就是,告诉你怎么改代码,啥东西变成啥东西之类的。

说是运算符,其实更像是指令。

有的算符是多语言共有的,也有的是不同语言独特的。

变异测试

用处主要有两点,一个是检查是否不存在我故意插入的错误,另一个是检查假如我造了一组奇怪的数据,是否会在某种情况下跑错。

常用的变异主要是:ABS(用绝对值代替),AOR(替换算术符号),LCR(替换逻辑符号),ROR(替换关系符号),UOI(新增或改变一元运算符)。

变异测试的流程

  1. 构造变异体(变异后的代码)。要控制变量,保持每一个变异体只有一个变异。
  2. 设计测试数据和测试点。
  3. 用原程序测试这些数据。
  4. 原程序和变异程序跑出来结果,如果不同,那就说明这组数据「杀掉」了这个变异体。(想象一下,你出题,应当卡掉所有错误做法。把 std 视作原程序,选手程序当作变异体,如果跑出来结果不一样,就杀掉(拒掉))。如果相同,那说明这个变异体具有相同功效。注意相同功效可能是因为原程序错了(AC 掉)。
  5. 测试目标是,杀掉所有的变异体(卡掉所有错解)。

变异得分 Mutation score

总共 $x$ 个变异体,杀掉了 $y$ 个,那么变异得分就是 $\frac{y}{x}$。如果编译得分是 $100\%$,就说这个测试数据是「足够变异(mutation adequate」的,卡掉了所有错解,好!

小结

优点

  • 可以构造出一些原本没有的错误
  • 可以体现测试数据是否足够好

缺点

  • 如果代码当中的运算量非常大,可能会产生非常大数目的变异体
  • 给变异体进行测试,需要花费很多时间