1. 基于 jacoco 的功能测试代码覆盖率实践

1.1 目前主流代码覆盖率统计工具

java代码覆盖率插桩工具 代码覆盖率 jacoco_Server

考虑到方案实施的难度很大取决于工具是否仍保持维护更新,所以选择 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 服务)

java代码覆盖率插桩工具 代码覆盖率 jacoco_Jenkins_02

配置完成后,可直接重启 tomcat 服务,查看 logs 目录下的 catalina 日志,查找 jacocoagent 字段,若有,则代表配置成功。

第三部:添加配置 ant build.xml 文件,随便存储在哪里都成,具体配置如下:

java代码覆盖率插桩工具 代码覆盖率 jacoco_java代码覆盖率插桩工具_03

java代码覆盖率插桩工具 代码覆盖率 jacoco_tomcat_04

java代码覆盖率插桩工具 代码覆盖率 jacoco_tomcat_05

1.3 本地生成覆盖率报告

以上配置完成后,可进行对应的功能测试操作,通过 ant dump 命令,可动态获

取覆盖率数据,不需要停止 tomcat 服务器。

备注: Jenkins 的 Jacoco plugin 可以根据.exec 文件直接生成覆盖率报告,并在 Jenkins 中生成图

表等等。那样的话,ant report 这个任务就没用了。可直接在 jenkins 中配置,在每次项目构建的时候自

动执行 report,这样就不需要将项目源码文件 checkout 到本地

➢打开 cmd 命令行窗口,进入 build.xml  所在目录,执行 ant dump,

若成功,会输出如下信息:

java代码覆盖率插桩工具 代码覆盖率 jacoco_java代码覆盖率插桩工具_06

➢在执行 ant report。jacoco 就会在你指定的路径生成覆盖率报告了

java代码覆盖率插桩工具 代码覆盖率 jacoco_Server_07

java代码覆盖率插桩工具 代码覆盖率 jacoco_tomcat_08

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

java代码覆盖率插桩工具 代码覆盖率 jacoco_Jenkins_09

➢ 配 置 sonar-scanner 配 置 文 件 , 修 改 sonar-scanner-3.0.3.778-windows\conf\sonar-scanner.properties 文件

java代码覆盖率插桩工具 代码覆盖率 jacoco_java代码覆盖率插桩工具_10

第三步:

➢配置 SonarQube 系统

访问 http://127.0.0.1:9000,如果不是本机就输入 http://IP:9000

java代码覆盖率插桩工具 代码覆盖率 jacoco_java代码覆盖率插桩工具_11

第四步:

对应项目工程添加 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 重新执行一遍,会显示详细报错信息。成功应

有如下内容输出:

java代码覆盖率插桩工具 代码覆盖率 jacoco_java代码覆盖率插桩工具_12

重新访问 http://127.0.0.1:9000 展示效果如下:

java代码覆盖率插桩工具 代码覆盖率 jacoco_Server_13

java代码覆盖率插桩工具 代码覆盖率 jacoco_Jenkins_14

java代码覆盖率插桩工具 代码覆盖率 jacoco_Jenkins_15

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