基于 jacoco 的功能测试代码覆盖率实践
1. 基于 jacoco 的功能测试代码覆盖率实践
1.1 目前主流代码覆盖率统计工具
考虑到方案实施的难度很大取决于工具是否仍保持维护更新,所以选择 jacoco 来进行实践。
Jacoco 是一个开源的覆盖率工具。Jacoco 可以嵌入到 Ant 、Maven 中,并提供了 EclEmma Eclipse 插件,也可以使用 Java Agent 技术监控 Java 程序。很多第三方的工具提供了对 Jacoco 的集成,如 sonar、Jenkins、IDEA。
Jacoco 包含了多种尺度的覆盖率计数器,包含指令级(Instructions,C0 coverage),分支(Branches,C1 coverage)、圈复杂度(Cyclomatic Complexity)、行(Lines)、方法(Non-abstract Methods)、类(Classes)。
➢ Instructions:Jacoco 计算的最小单位就是字节码指令。指令覆盖率表明了在所有的指令中,
哪些被指令过以及哪些没有被执行。这项指数完全独立于源码格式并且在任何情况下有效,不需要类文件
的调试信息。
➢ Branches:Jacoco 对所有的 if 和 switch 指令计算了分支覆盖率。这项指标会统计所有的分支数
量,并同时支出哪些分支被执行,哪些分支没有被执行。这项指标也在任何情况都有效。异常处理不考虑在分支范围内。
➢ Cyclomatic Complexity:Jacoco 为每个非抽象方法计算圈复杂度,并也会计算每个类,包,组的复杂度。根据 McCabe1996 的定义,圈复杂度可以理解为覆盖所有的可能情况最少使用的测试用
例数。这项参数也在任何情况下有效。
➢ Lines:该项指数在有调试信息的情况下计算。
➢ Methods:每一个非抽象方法都至少有一条指令。若一个方法至少被执行了一条指令,就认为它被执行过。因为 JaCoco 直接对字节码进行操作,所以有些方法没有在源码显示(比如某些构造方法和由编
译器自动生成的方法)也会被计入在内。
➢ Classes:每个类中只要有一个方法被执行,这个类就被认定为被执行。同 5 一样,有些没有在源码声明的方法被执行,也认定该类被执行。
1.2 jacoco 部署准备工作
➢下载 jacoco.zip http://www.eclemma.org/jacoco/index.html
➢下载安装 ANT,具体可参考百度,需配置环境变量。
第 一 步 : 解 压 下 载的 jacoco-0.7.9.zip 文 件 , 将 lib 文 件 夹 下 的 jacocoagent.jar 包拷贝放到对应 tomcat 服务器的 lib 目录下
第二步: 修改 tomcat\bin 目录下的 catalina.bat 文件,在 setlocal 后添加如下代码:
set "JAVA_OPTS=-javaagent:%CATALINA_HOME%\lib\jacocoagent.jar=includes=com.thinkgem.
jeesite.*,output=tcpserver,port=8144,address=127.0.0.1 - Xverify:none"
(限 Windows 环境,其他系统略有不同,需先停掉 tomcat 服务)
配置完成后,可直接重启 tomcat 服务,查看 logs 目录下的 catalina 日志,查找 jacocoagent 字段,若有,则代表配置成功。
第三部:添加配置 ant build.xml 文件,随便存储在哪里都成,具体配置如下:
1.3 本地生成覆盖率报告
以上配置完成后,可进行对应的功能测试操作,通过 ant dump 命令,可动态获
取覆盖率数据,不需要停止 tomcat 服务器。
备注: Jenkins 的 Jacoco plugin 可以根据.exec 文件直接生成覆盖率报告,并在 Jenkins 中生成图
表等等。那样的话,ant report 这个任务就没用了。可直接在 jenkins 中配置,在每次项目构建的时候自
动执行 report,这样就不需要将项目源码文件 checkout 到本地
➢打开 cmd 命令行窗口,进入 build.xml 所在目录,执行 ant dump,
若成功,会输出如下信息:
➢在执行 ant report。jacoco 就会在你指定的路径生成覆盖率报告了
2. 基于 jacoco + SonarQube + sonar-scanner 的集成实践
SonarQube 能够提供对代码的一整套检查扫描和分析功能,可以通过 sonar-scanner 完成对各开发环境和软件的支持。通过整合 jacoco 不仅可以展示代码扫描结果,也能图形化显示测试覆盖率情况。
2.1 SonarQube 准备工作
第一步:
➢下载 SonarQube 和 sonar-scanner,并解压 https://www.sonarqube.org/downloads/ 将 sonar-scanner\bin,路径添加到环境变量
➢安装 MySql,并创建数据库(也可使用内置数据库,实际使用会很慢)
-- 创建数据库:
CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci; -- 创建SonarQube Server访问数据库的用户:
CREATE USER 'sonar' IDENTIFIED BY 'sonar';
-- 配置SonarQube Server访问数据库用户的权限
GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar';
GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar';
-- 更新权限:
flush privileges;
第二步:
➢配置 SonarQube 配置文件,打开 SonarQube 下的 conf/sonar.properties
➢ 配 置 sonar-scanner 配 置 文 件 , 修 改 sonar-scanner-3.0.3.778-windows\conf\sonar-scanner.properties 文件
第三步:
➢配置 SonarQube 系统
访问 http://127.0.0.1:9000,如果不是本机就输入 http://IP:9000
第四步:
对应项目工程添加 properties 配置文件,文件内容如下:
# 指定 SonarQube instance 必须是唯一的
sonar.projectKey=BR_CR2794_20170419
# 设置 SonarQube UI 显示的名称
sonar.projectName= hrms
sonar.projectVersion=1.0
sonar.language=java
# 指定 src 和 classes 文件夹位置,当可以是全路径,如果是当前工程根目录下用“.”表示也可以
sonar.sources=src
sonar.java.binaries=target
# 不参与分析的某个文件夹或者忽略某个文件夹
# sonar.inclusions=src1/**,src3/**
# sonar.exclusions=src2/**,src4/**
# 源码编码,默认是系统编码
sonar.sourceEncoding=UTF-8
# Set jacoco Configuration
# 指定代码覆盖率工具
sonar.core.codeCoveragePlugin=jacoco
# 指定 exec 二进制文件存放路径
sonar.jacoco.reportPaths=D:/covge/jacoco.exec
# 以下属性非必须,具体含义参考百度
sonar.dynamicAnalysis=reuseReports
sonar.jacoco.reportMissing.force.zero=false
2.2 SonarQube 执行项目分析
以上配置完成后,打开 cmd 窗口,进入工程根目录,执行 sonar-scanner 命
令,若报错,可在命令后加上 -X 重新执行一遍,会显示详细报错信息。成功应
有如下内容输出:
重新访问 http://127.0.0.1:9000 展示效果如下:
2.2SonarQube 集合 jenkins 和 maven 使用
➢ 在 Jenkins 中安装和使用 SonarQube 的先决条件:安装插件 SonarQube Plugin,并且 Jenkins 插件 SonarQube Plugin 在配置位置 Jenkins->Configuration->Configure System->SonarQube servers 中的选项 Server URL 要配置正确,使用已经安装好的 SonarQube Server 的 URL
➢ 修 改 maven 配 置 setting.xml , 参 照 官 方 配 置 :
https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Ma ven
<settings>
<pluginGroups>
<pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
</pluginGroups>
<profiles>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!-- Optional URL to server. Default value is http://localhost:9000 --> <sonar.host.url>
http://myserver:9000
</sonar.host.url>
</properties>
</profile>
</profiles>
</settings>
修改 Maven 配置之后,在 Maven 构建指令上加上一个 Goals 即可:
$SONAR_MAVEN_GOAL -Dsonar.host.url=$SONAR_HOST_URL