测试开发之单元测试-基于Jacoco的单元测试代码覆盖率统计

原创
🍪
陈琦
2023-05-23 09:00:00
3305
摘要:本文中介绍的Jacoco是一款流行的开源Java代码覆盖率工具,可以进行代码覆盖率统计。

代码覆盖率(Code coverage)用于描述一次测试执行中,被执行的代码占总代码的比率。这里的一次执行,可以是一次单元测试,也可以是一段时间内的手工测试执行;覆盖率除了按代码行进行计算,也可以统计程序代码的分支、函数和类的覆盖比率。

本文中介绍的Jacoco是一款流行的开源Java代码覆盖率工具,其覆盖率指标主要有以下几个:

  • 指令 Instructions

针对Java字节代码指令的覆盖,是Jacoco最小粒度的指标。它提供总量、被执行和遗漏和数量信息。

  • 分支 Branches

基于If、Switch语句分支来计算覆盖率,不包括异常处理分支。可在文件、类和方法3个层面进行统计。

  • 行、方法和类

针对源代码的中的行、方法和类,进行总数、被执行、遗漏数量的统计。

下面我们给出一个例子,展示如何在Maven执行单元测试时,使用Jacoco统计代码覆盖率。完整被测项目的源代码可参考这里

新建一个基于Maven的TestNG单元测试项目,在pom.xml中加入以下依赖。


<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>7.0.0</version>
</dependency>
<dependency>
  <groupId>com.google.inject</groupId>
  <artifactId>guice</artifactId>
  <version>3.0</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.uncommons</groupId>
  <artifactId>reportng</artifactId>
  <version>1.1.4</version>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
    </exclusion>
  </exclusions>
</dependency>


在pom.xml中增加以下2个插件,分别用于TestNG测试执行和Jacoco覆盖率统计。


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.22.1</version>
  <configuration>
    <testFailureIgnore>true</testFailureIgnore>
    <suiteXmlFiles>
      <suiteXmlFile>${testng.suite}</suiteXmlFile>
    </suiteXmlFiles>
    <argLine> @{argLine} -Dfile.encoding=UTF-8</argLine>
  </configuration>
</plugin>
<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.9</version>
  <executions>
    <execution>
      <goals>
        <goal>prepare-agent</goal>
      </goals>
    </execution>
    <execution>
      <id>report</id>
      <phase>test</phase>
      <goals>
        <goal>report</goal>
      </goals>
    </execution>
  </executions>
</plugin>


下面我们编写一个被测试的Java类Count。


package com.deeptest.sample.jcoco;
public class Count {
    public int add(int x ,int y){
        int i = 0;
        if (i == 0) {
            i++;
        } else {
            i--;
        }
        return x + y;
    }
    public int sub(int x ,int y){
        return x - y;
    }
    public int div(int x ,int y){
        return x / y;
    }
}


再写一个TestNG单元测试类。


package com.deeptest.sample.jcoco;
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertEquals;
public class CountTest {
    @Test
    public void testAdd() {
        Count count = new Count();
        int result = count.add(2,2);
        assertEquals(result, 4);
    }
}


在src/test/res中创建一个测试套件,它被pom.xml中的maven-surefire-plugin插件调用,并会在maven构建的test生命周期中执行。


<?xml version="1.0" encoding="UTF-8"?>
<suite name="套件">
    <test name="用例">
        <classes>
            <class name="com.deeptest.sample.jcoco.CountTest" />
        </classes>
    </test>
</suite>


进入项目根目录,执行以下命令开始测试。第一次执行会下载相应的依赖,时间会相对比较久一些。


mvn clean test


结束后jacoco会在target/site/jacoco下生成XML和HTML格式的覆盖率报告,其中HTML报告用浏览器打开后如下。

最后,我们花点时间给大家介绍下maven构建的过程。在pom.xml我们定义了两个插件,分别用于jacoco的执行和java代码的打包。
这里重点介绍下jacoco-maven-plugin插件,其下名为prepare-agent的goal,默认会在maven的initialize生命周期中执行(pom.xml中不配置phase的goal,会默认使用插件的设置),用于准备代理(你可以理解为向Java虚拟机注入代码,添加获取VM执行信息的钩子);名为report的goal,用于在测试完成后,生成覆盖率报告。

如果不使用pom.xml的execution执行器,也可以用以下命令来代替。注意:它是一整行的命令,为了加注释分成了多行。


mvn clean -Dmaven.test.skip=false                              # 不忽略测试
    org.jacoco:jacoco-maven-plugin:0.8.9:prepare-agent         # 准备Jacoco代理
    compile test-compile                                       # 编译代码
    org.apache.maven.plugins:maven-surefire-plugin:2.22.1:test # 单元测试
    org.apache.maven.plugins:maven-jar-plugin:2.4:jar          # 打包JAR
    org.jacoco:jacoco-maven-plugin:0.8.9:report                # 生成Jacoco覆盖率报告
    -Dmaven.test.failure.ignore=true -Dfile.encoding=UTF-8     # 一些参数



Q: 什么是Jacoco代码覆盖率工具?

A: Jacoco是一款开源的Java代码覆盖率工具,用于统计指令、分支、行、方法和类的覆盖率。


Q: 如何使用Maven执行Jacoco的代码覆盖率统计?

A: 可以在pom.xml中配置jacoco-maven-plugin插件,并通过执行`mvn clean test`命令来生成覆盖率报告。


Q: Jacoco支持哪些代码覆盖率指标?

A: Jacoco支持指令、分支、行、方法和类的代码覆盖率统计。

推荐阅读

测试开发专题-开篇

随着DevOps和敏捷过程越来越广泛地被采用,软件测试、特别是自动化测试得到了迅速的发展。
陈琦 2021-05-20

测试开发之前端篇-浏览器开发者工具使用

Chrome开发者工具是浏览器內置的、用于对网页浏览有关的内容和行为进行查看和调试的工具。可使用快捷键Ctrl + Shift + J ( 在 Mac 上使用 Cmd + Opt + J) 打开,他显示在浏览器的底部,包涵了以下几个Tab的功能。 Console 控制台 用于查看日志和调试JavaScript脚本。以上是百度首页的控制台,大家可以发现开发者用日志的形式打印了一条招聘信息。 在...
aaronchen2k 2021-10-19

测试开发之系统篇-按需创建测试虚拟机

首先,我们来了解一下KVM虚拟机有关的几个概念和工具。 kvm:基于内核的虚拟机(引擎) qemu:用于模拟虚拟机IO设备 qemu-img:虚拟机磁盘管理工具 libvirt:虚拟化服务的API接口 virsh:基于libvirt实现的命令行工具 qemu-manager:图形化管理工具 新建KVM虚拟机时,可以指定另一磁盘文件作为BackingFi...
aaronchen2k 2021-06-21

测试开发之系统篇-安装KVM虚拟机

虚拟机(Virtual Machine)和容器(Container)是两种流行的虚拟化技术。 虚拟机模拟机器的硬件,包括了完整的操作系统和应用,它一旦被开启,预分配给它的资源将全部被占用。容器是运行在宿主机上的一个进程,多个容器之间使用同一个宿主机的操作系统内核。容器相对于虚拟机启动更快、占用资源更少,但隔离和安全性要弱于虚拟机。 测试人员为了准备不同的测试环境,往往使用可视化的VMW...
aaronchen2k 2021-06-09
返回顶部
客服头像
高丽亚
高级客户经理
客服微信
17667930330
3645260865
统一服务热线 4006-8899-23
我要提问提问有任何问题,您都可以在这里提问。问题反馈反馈点击这里,让我们聆听您的建议与反馈。