因为这篇笔记会涉及多个tools, 避免大家阅读混乱, 目录 :
- Evosuite的用例在jacoco / Pitest 下的表现
- 10 ways to ramp up automation test coverage(增加自动化测试覆盖率的10种方法)
首先, 我一直认为理论是指导实践的最佳路径, 所以如果你对测试的所以基础理论还有些许疑惑, 看这个:https://martinfowler.com/testing/单元测试简单的概念 : 测试应用程序中最小的可测试软件片段,以确定它的行为是否符合预期. 通常这个片段是类级别, 方法级别.代码覆盖率是发现代码中未测试部分的一个维度, 注意, 是一个维度, 并不是全部维度的体现. 它也并不能作为测试行为好坏的唯一准则.
现实就是如果你把一定程度的覆盖率作为一个KPI目标,人们会努力实现它。
问题是高覆盖率的数字太容易通过低质量的测试得到, 从而分散你对真正重要的东西的测试.(人们可能通过删减代码量(一定程度上实现了clean code?) 以及 进行毫无意义的用例(setter/getter测试?) 来达到高的覆盖率)
当然,较低的覆盖率(比如低于一半)是肯定不对的, 我们更应该去关注测试充分性, 而不是它其中的一部分-覆盖率.那测试的度量的其他部分是什么呢? 我认为有几个方面通常,度量测试覆盖率的工具将在测试套件运行期间监视代码 , 工具将尝试在测试套件运行期间检查每个编写的代码行是否至少被调用一次。这是合乎逻辑的——因为在测试套件运行期间没有被调用的行实际上是未经测试的.Jacoco - Java世界的测试覆盖率工具对哪些做了统计呢? 类, 函数、语句、分支和条件覆盖率,来得到最终的统计数据.但80%的覆盖率只代表了80%的代码, 分支, 条件 被执行了, 却没有进行验证来保证.马克·吐温的一句名言:“有三种谎言:谎言、该死的谎言和统计数字。"
变异测试(mutation testing)带来了什么?什么意思呢, 试想一个场景, 你写了1000条case, 怎么验证它的有效性, 不是冗余甚至错误的呢? 在程序运行时修改代码的逻辑后(切换数学运算符,更改返回类型,删除调用等), (比如>10 改为>=10) 如果你的测试用例fail, 那你的用例是正确且有效的! 反之不论代码如何修改,你的用例一直是pass的, 那我不得不怀疑你是否正确验证了它.但它测试充分了吗?? 很明显, 有一个边界值(101)你并没有覆盖测试到.fast - can analyse in minutes what would take earlier systems days
easy to use - works with ant, maven, gradle and others
actively developed
actively supported
把它集成很简单, 就不多说了,测试结果会在target/pit-reports 中可参考以下链接, 也特别推荐一个社区 dev.to 里边有不少有意思的思路, 以及https://www.baeldung.com/ java spring很多专业的文章链接:https://dev.to/silviobuss/increase-the-quality-of-unit-tests-using-mutation-with-pitest-3b27现在问题来了, 我怎么才能写出好的单测用例呢? 在交付压力下, 我的用例写起来很不充分, 覆盖率可能都达不到50%, jacoco都过不去, 更别提pitest了.链接:http://www.evosuite.org/mvn compile evosuite:generate我们当然要拿Jacoco 和 Pitest来验证一下依然是100%, 当然时间稍微加长了, 因为Evosuite生成的用例中它用了一些mock在EvoSuite的bytecode instrumentation有两种选择如下:一、在EvoSuite的 @RunWith(EvoRunner.class)中,会调用EvoSuite自己的classloader,而在这个过程中就调用它自己提供的bytecode instrumentation来完成对应的分析。
这就导致了EvoSuite的bytecode instrumentation是早于其他代码覆盖工具完成。
二、EvoSuite会启动一个Java的代理,代理会拦截全部的class loading,然后加入其EvoSuie的bytecode instrumentation。
EvoSuite目前默认是第一种,但是如果可以使用第二种,建议使用第二种,因为第二种可以有效避免和类似Jacoco工具的bytecode instrumentation的冲突,但是如果在测试在代理启动前就执行了,那么就不会起作用了范围会报EvoSuite的错误。在使用过程中,如果发现代码覆盖报告全部是0,可以尝试通过一下方式切换上面的两种bytecode instrumentation方式。切换方式: 生成用例中 修改separateClassLoader = true为false(从方式1 变成方式2)10 ways to ramp up automation test coverage(增加自动化测试覆盖率的10种方法)我相信很多人对这个话题最感兴趣, 如果提高自动化测试覆盖率呢?我这里并不包括单元测试覆盖率, 因为如果你践行了TDD, 提供覆盖率并不是很难的事情, 但对于E2E自动化测试, 包括API及UI, 提供覆盖率还是有一定难度的.尽早的参与到story中, 根据真实的需求去编写测试用例
预估自动化测试的工作量, 包括需要的数据准备, 测试方法, 风险, 比如我需要mock吗? 需要mock哪些数据? service?
写API测试用例一定要包括验收标准, 甚至在story上也要有相应的API接口的标准.
监视git 提交, 第一时间知道代码变更, 而且你更能清楚哪些代码会影响哪些功能以及自动化测试用例
把每一个手工测试的bug 写入自动化测试用例, 不断迭代测试用例
了解覆盖率工具比如Jacoco 检测了哪些
最好创建一个自动化测试的backlog board, 以让你清楚的知道自动化测试用例的迭代
排定优先级, 对P0 test case进行多次迭代
测试基础理论的落实, 边界值/参数异常/数据异常等
紧密与开发沟通, 发现开发的废代码, 从而从基数上达到高覆盖率的目标
在上面我介绍了EvoSuite, 它是基于遗传算法进化测试套件, 但其实现在业内已经发展出一个新的测试类型 - Fuzz Test 模糊测试, 简单描述就是按照一定的算法生成大量的随机数列进行测试, 并及时将bug及覆盖率展示.Randoop 随机生成方法调用序列,但不使用代码覆盖率反馈Java PathFinder 支持 Java 程序的符号执行Korat 系统地研究了 Java 谓词的输入空间JQF 一个在 Java 中执行覆盖引导模糊测试的平台1、JQF 是为那些希望在 Java 程序中发现错误的人设计的,也为那些希望实现新的模糊算法的人设计的
2、JQF 会检测测试程序的字节码,并使用在覆盖率引导的模糊循环中生成的输入来连续执行测试
3、JQF 的输入生成机制是可扩展的。
研究人员可以通过扩展 JQF 的 Guidance 接口来实现自定义模糊算法
4、JQF 已经成功地发现了广泛使用的开源软件(如 OpenJDK、Apache Commons 和 Google Closure 编译器)中 42 个以前未知的错误。
链接:https://github.com/rohanpadhye/JQF