51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 2983|回复: 1
打印 上一主题 下一主题

[原创] 服务端代码覆盖率统计平台实现(全量、变更)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2018-11-16 18:38:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.背景
覆盖率是度量测试完整性的一个手段,但不建议作为质量目标,可以当做一种发现漏测代码的手段。
基于公司目前的测试现状,打算研发覆盖率统计工具,辅助大家发现日常功能测试、自动化测试过程中漏测的代码,以补充测试场景,防止漏测。
目前主要支持统计服务器端的代码覆盖率,包括全量覆盖率和变更覆盖率。

2.总体设计
使用场景图:
  
功能列表图:
  
3.细节设计
覆盖率报告生成流程图:


3.1 Jacoco介绍
Jacoco是一个开源的Java代码覆盖率工具,Jacoco可以嵌入到Ant 、Maven中,并提供了EclEmma Eclipse插件,也可以使用JavaAgent技术监控Java程序。很多第三方的工具提供了对Jacoco的集成,如sonar、Jenkins等。关于JaCoCo的注入原理以及注入方式,网上有很多资料,这里不过多赘述。在这里我们主要统计远程测试覆盖率,选择的是 On-the-fly 模式。只需在 JVM 中通过 -javaagent 参数指定 jar 文件启动 Instrumentation 的代理程序,代理程序在通过 Class Loader 装载一个 class 前判断是否需要注入 class 文件,将统计代码插入 class ,测试覆盖率分析就可以在 JVM 执行测试的过程中完成。

我们的设计方案是基于jacoco做相应改造(这里为什么需要改造jacoco呢?因为jacoco不支持变更覆盖率报告的生成),生成所需的覆盖率模型,并通过jacoco开放的api实现相关功能。

jacoco详细介绍,具体参见:https://www.jacoco.org/jacoco/trunk/doc/mission.html
3.2 全量覆盖率
3.2.1 java agent部署
JVM中通过-javaagent参数指定特定的jar文件启动Instrumentation的代理程序,代理程序在通过Class Loader装载一个class前判断是否转换修改class文件,将统计代码插入class,测试覆盖率分析可以在JVM执行测试代码的过程中完成。下面举2个例子,说明被测应用如何部署jacoco:

tomcat方式:
a.修改tomcat的bin目录下的配置文件catalina.sh的JVM启动参数如下:
JAVA_OPTS="$JAVA_OPTS -javaagent:[yourPath/]jacocoagent.jar=includes=*,output=tcpserver,address=本机ip,port=28044"
b.重启tomcat
c.执行ps -ef|grep jacocoagent.jar 如果有jacocoagent服务说明部署成功

jar方式:
java -javaagent:[yourPath/]jacocoagent.jar=includes=*,output=tcpserver,address=本机ip,port=28044 -jar springboot-xxx.jar

部署方式网上很多参考资料,这里重点强调下:现在很多应用都是基于docker部署,建议将jacoco agent的部署集成到公司内部的部署平台。
-javaagent参数配置可以参考:https://www.jacoco.org/jacoco/trunk/doc/agent.html

3.3.2 获取exec文件(二进制文件,有覆盖率相关信息)
上面的步骤部署jacoco agent之后,我们就可以通过tcp的方式获取exec文件,部分代码片段如下:
  
也可参见官方demo:https://www.jacoco.org/jacoco/tr ... tionDataClient.java
3.3.3 生成覆盖率报告
生成覆盖率报告的前提是需要有被测服务的源码和编译后的class文件,故会先下载被测服务的源码,然后编译,代码片段如下:
  
编译是直接运行本地mvn命令实现的:
  
有了源码和编译后的class文件,则可以生成覆盖率报告,代码片段如下:
  
  
  



也可参看官方demo:https://www.jacoco.org/jacoco/tr ... eportGenerator.java

至此,全量覆盖率报告生成已完成。因为jacoco原生就支持全量覆盖率,所以不需要对jacoco进行改造,使用起来也比较简单。
3.3 变更覆盖率
3.3.1 对jacoco改造
在讲具体实现步骤之前,先谈下我们对 JaCoCo 做的改造思路。 JaCoCo 的注入逻辑用的是 ASM 库,对于没有接触过字节码注入技术的测试同学来说,改造注入逻辑需要花费较多时间,这里我们用了一个比较快速简单的方式:前面生成全量覆盖率数据的流程不变,只对解析exec文件生成报告做改造,生成我们所需要的覆盖率模型。JaCoCo 对 exec 的解析主要是在 Analyzer 类的 analyzeClass(final byte[] source) 方法。这里面会调用 createAnalyzingVisitor 方法,生成一个用于解析的 ASM 类访问器,继续跟代码,发现对方法级别的探针计算逻辑是在 ClassProbesAdapter 类的 visitMethod 方法里面。所以我们只需要改造 visitMethod 方法,使它只对提取出的每个类的新增或变更方法做解析,非指定类和方法不做处理。改造后的核心代码片段如下:
  

3.3.2 获取差异代码并切割刀方法粒度
这部分会涉及到较多的 Git 操作,我们是用 JGit 实现的。在这一步的主要流程是获取基线提交与被测提交之间的差异代码,然后过滤一些需要排除的文件(比如非 Java 文件、测试文件等等),对剩余文件进行解析,将变更代码解析到方法纬度,如何解析到方法维度?我们使用JDT分析源码并解析出每个方法,然后算出新旧文件的方法的md5值,最后比较md5值是否相同,如果不相同,说明该方法有变更。
获取变更文件的代码片段如下:
  



获取变更方法的代码片段如下:
  
4. 效果
工具整体效果如下:
  

覆盖率报告如下:
  


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
 楼主| 发表于 2018-11-19 10:20:22 | 只看该作者
帖子里的图片无法访问,感兴趣的可以关注我的公众号:笑笑测试笔记
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-4-19 23:38 , Processed in 0.068687 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表