- JDK 8
我只有JDK 17,所以改了下Language Level,保证不会使用新特性就行(后面会讲,变异测试需要jdk8) - Junit 4.12(在pom.xml中已指定好)
- 我用的是 IDEA,毕竟2024年mooctest比赛终于可以不用那个难用得要死的eclipse了
注意,一个Test方法只能测试一处异常。如果你想测试一个对象方法里会有的多个异常,还是只能分成多个测试方法分开测。
其实有个允许一个Test方法内测试多个异常的函数,但是是Junit5中的。通过参考23年省赛答案,我发现了答案中对assertThrows进行了自己的实现。
是使用 进行比较,比较两个引用是否指向堆上的同一个对象
第三个参数是指误差范围
查看源码可以发现就是差<=误差就行
输出为
众所周知测试肯定不能修改待测代码,但是对于只有 sout 的 void 方法,我们肯定也是要测试。我们可以通过输出重定向的方法捕获输出内容到变量中,然后 assert。
变异测试的原理就是,把待测代码(在字节码层面改)改一下,如果我们的测试代码的 assert 依然通过(即变异子存活),那说明代码存在问题。比如我们测试 这个减法函数,如果我们的 junit 写的是 ,那么变异子将subtract的减法改成加法,这个 assert 依然通过,说明咱们的测试存在疏漏。
我的理解是变异测试不是让开发人员自行对代码单测试的,而是让测试人员完善测试用例的。
我们使用 pitest 这个工具进行测试。包在 pom.xml 里已经有了。
我们使用下面的命令启动测试。
注意如果版本 >= jdk9,会报错
所以就只能老老实实用 jdk8 了…
按下面这样配一个运行按钮,会方便一点。注意填入的命令是

运行成功后,查看即可

可能即便测 coverage 已经全部 pass 了,pitest 这里还是有报错
可能是因为多个方法共享的变量(如静态变量等)被修改导致测试不通过(虽然我也不知道是哪里有问题)。可以看下面的例子,各个Test方法是从上到下执行的,修改 cnt 会影响在另一个方法里的测试。
突变子列表,这个链接介绍了有哪些突变子以及对应做了什么突变。浏览一下可以方便我们看 index.html 里内容的时候知道是哪些变异子活下来了。
这些是运行 mutation 覆盖率测试时默认激活的 mutator:
也可以自行配置其他突变子,这会导致测试时间变长,但能发现更多问题。
在index.html中,悬停在红色数字上可以看到下面黄色区域的内容,就是对应行的存活变异子。
下面的例子就是说,第150行有两个变异子存活,即条件边界改变和条件取反。比如一个是变异成这种,一个是这种。我们就要针对这些情况再添加相关assert。

- 某些情况可以多用循环,增加覆盖率的同时,也更好杀死变异体。
- 先用 idea 的 diagram 看各个类的依赖关系,先覆盖最上层的类的方法,这样也会覆盖一些底层方法。如果先从底层类开始,会浪费时间。同时最好先提高覆盖率,再去弄变异测试,别花费时间在不提高分数的测试用例的编写上。
- 尽量避免修改共享变量,如果一定要修改,尽量改后还原。
- 注意判题标准。反正24年的是下面这样。所以不要只做覆盖率。然后各个Test方法把名称和注释都弄得可读性搞些。运行效率的话,虽然我上面说了可以用循环,但是感觉只要不写死循环就OK吧。
按以下五个维度进行评分。
- (30%)分支覆盖率:代码分支覆盖率。
- (30%)变异杀死率:参阅PIT工具网站指定的常见变异类型。
- (20%)可读性与可维护性:参阅各大企业的测试同样指南进行评分。
- (20%)脚本运行效率:针对该题为每个覆盖率区间给定一个基准时间,分数为(基准时间-运行时间)/基准时间。
脚本编写效率:总分=上述分数累加,总分相同则按提交时间二次排序。
- 可读性与维护性:可以使用这个插件检查代码,或者直接用 idea 的 problems 面板查看。建议最后留五分钟改改代码可读性。
- 打完预选赛,根本做不完分支覆盖,可能是我太菜了。所以变异覆盖率也只能靠做分支覆盖时多加几种边缘值assert顺便提升。真的没空专门弄变异覆盖。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/37583.html