欢迎进入🔗中通快递官网了解更多资讯
1.背景
原生的JaCoCo代码覆盖率工具,不支持增量代码覆盖率报告生成,因此中通测试开发团队做了二次开发,推出V1.0版,前面的推文中已有介绍。但是在实际使用场景中,存在同一分支上反复修改代码并多次部署,测试执行时不会再在没有改动的功能上重新测试,这就导致了明明测试已经覆盖了,但是生成的覆盖率报告数据为空的情况。针对这个无法满足实际场景需求的现状,我们推出了V2.0版,实现了同一个分支多次部署代码覆盖率报告的合并。
2.JaCoCo增量代码覆盖率设计思路
这里主要需要解决的点在于获取增量代码并解析生成覆盖率报告。网上有很多相关的资料,这里就不多介绍了,简单介绍下改造大致的几个步骤:
- 获取测试完成后的exec文件
- 获取基线和被测分支之间的差异代码
- 通过指定代码仓库和开发分支,解析开发分支和master之间的差异
- 改造后的JaCoCo支持针对差异代码生成覆盖率报告
3.同一个分支多次部署报告合并的实现
针对同一个分支多次修改代码并部署,生成多份覆盖率报告,导致明明测试已经覆盖了,但是覆盖率代码和编译代码不一致的情况下,生成的覆盖率报告数据无法合并的问题。网上也看到不少同行都有类似的问题,但一直未找到真正落地解决的方案。在此重点介绍一下我们的设计思路与实现方案。
代码覆盖率流程
-
每次生成代码覆盖率报告的同时,生成一份xml覆盖率报告。
-
每次获取差异代码前,先解析上一次生成覆盖率报告时生成的xml报告,生成一个对象,为后续流程使用。
-
合并覆盖率后,通过版本比较,判断方法是否在上一个版本中。如果存在于上一个版本中,则检查是否在上一个版本中被覆盖过,从而完成差异代码的获取。
-
完成获取差异代码后,与第2)步生成的对象,通过方法名和行号,遍历比对,生成新的exec文件。
-
解析新生成的exec文件,通过改造后的Report服务根据方法名,设置方法对应的行号,重新渲染行覆盖情况,从而生成合并后的增量代码覆盖率报告。
部分核心代码如下:
/**
* 判断方法是否在上一个版本中
**/
private static boolean isMethodExistInLastCommit(MethodDeclaration method, String lastCommitId, GitAdapter gitAdapter, String oldJavaPath)
throws IOException {
String lastClassContent = gitAdapter
.getTagRevisionSpecificFileContent(lastCommitId, oldJavaPath);
ASTGenerator lastAstGenerator = new ASTGenerator(lastClassContent);
MethodDeclaration[] lastMethods = lastAstGenerator.getMethods();
Map<String, MethodDeclaration> methodsMap = new HashMap<>();
for (int i = 0; i < lastMethods.length; i++) {
methodsMap.put(lastMethods[i].getName().toString() + lastMethods[i].parameters().toString(), lastMethods[i]);
}
if (ASTGenerator.isMethodExist(method, methodsMap)) {
return true;
}
return false;
}
/**
* 判断是否在上一个版本中被覆盖过
**/
private static void isCoveredByLastCommit(JSONObject reportObject, String packageName, String className,
MethodDeclaration method, G