龙空技术网

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

DeepTest 100

前言:

此时朋友们对“java测试类”大约比较珍视,小伙伴们都想要剖析一些“java测试类”的相关资讯。那么小编在网上收集了一些关于“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     # 一些参数

标签: #java测试类