Spring Boot集成jacoco实现单元测试覆盖统计

1.什么是jacoco?

JaCoCo,即 Java Code Coverage,是一款开源的 Java 代码覆盖率统计工具。支持 Ant 、Maven、Gradle 等构建工具,支持 Jenkins、Sonar 等持续集成工具,支持 Java Agent 技术远程监控 Java 程序运行情况,支持Eclipse、IDEA等IDE,提供HTML,CSV 等格式的报表导出,轻量级实现,对外部库和系统资源的依赖性小,性能开销小。 JaCoCo 支持从 JDK1.0 版本到 JDK1.8 版本 的 Java 类文件。但是,JaCoCo 工具所需的JRE 版本最小为 1.5。另外,1.6及以上版本的测试中的类文件必须包含有效的堆栈映射帧。

它有以下功能特性:

  • 指令(C0)、分支(C1)、行、方法、类型和圈复杂度的覆盖分析
  • 基于 Java 字节码,因此也可以在没有源文件的情况下工作。
  • 通过基于实时检测的Java 代理进行简单集成。通过 API 可以实现其他集成场景,例如自定义类加载器。
  • 与框架无关:基于 Java VM 的应用程序都可以顺利集成,例如普通 Java 程序、OSGi 框架、Web 容器或 EJB 服务器。
  • 与所有已发布的 Java 类文件版本兼容。
  • 支持不同 JVM 语言
  • 多种报告格式(HTML、XML、CSV)。
  • 在任何时间点,可以使用远程协议和 JMX 控制从覆盖代理请求执行数据转储。
  • 用于收集和管理执行数据并创建结构化覆盖率报告的Ant 任务
  • Maven 插件,用于收集覆盖信息并在 Maven 构建中创建报告。

非功能特性:

  • 简单的使用和与现有构建脚本和工具的集成。
  • 良好的性能,最小的运行时开销,尤其是对于大型项目。
  • 对外部库和系统资源的依赖最小的轻量级实现。
  • 综合文档。
  • 完整的API文档(JavaDoc)和 其他工具集成示例
  • 基于JUnit 测试用例的完整功能测试覆盖的回归测试。

2.代码工程

实验目标

实验单元测试覆盖率检测

pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-demo</artifactId>
        <groupId>com.et</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>jacoco</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.6</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>jacoco-report</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>jacoco-check</id>
                        <goals>
                            <goal>check</goal>
                        </goals>
                        <configuration>
                            <rules>
                                <rule>
                                    <element>PACKAGE</element>
                                    <limits>
                                        <limit>
                                            <counter>LINE</counter>
                                            <value>COVEREDRATIO</value>
                                            <minimum>0.0</minimum>
                                        </limit>
                                    </limits>
                                </rule>
                            </rules>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
                <configuration>
                    <forkedProcessExitTimeoutInSeconds>60</forkedProcessExitTimeoutInSeconds>
                    <forkCount>1</forkCount>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

controller

typescript 复制代码
package com.et.jacoco.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class HelloWorldController {
    @RequestMapping("/hello")
    public Map<String, Object> showHelloWorld(){
        Map<String, Object> map = new HashMap<>();
        map.put("msg", "HelloWorld");
        return map;
    }
}

测试类

java 复制代码
package com.et.jacoco;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import static org.hamcrest.core.StringContains.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ExtendWith(SpringExtension.class)
@WebMvcTest
@AutoConfigureMockMvc
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void getHello() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("HelloWorld")));
    }
}

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

3.测试

执行mvn clean test 会自动在项目目录:`target/site/jacoco/index.html` 即可查看到图形化的测试报告,如下:点击链接,你可以查看每个类的代码覆盖情况,如下:

四.总结

本文简单介绍 JaCoCo 最基本使用和上手,希望你可以通过官网探索更多的高级功能,关于覆盖率给你一些建议:

  • 覆盖率指标大多数情况下仅作为参考,不要用它作为考核指标
  • 不要过于追求覆盖率指标,100% 的覆盖率也不能代表你的项目没有 BUG

4.引用

相关推荐
Victor35610 小时前
MongoDB(2)MongoDB与传统关系型数据库的主要区别是什么?
后端
JaguarJack10 小时前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端·php·服务端
BingoGo10 小时前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端
Victor35610 小时前
MongoDB(3)什么是文档(Document)?
后端
MSTcheng.10 小时前
【C++】C++异常
java·数据库·c++·异常
大模型玩家七七11 小时前
基于语义切分 vs 基于结构切分的实际差异
java·开发语言·数据库·安全·batch
Coder_Boy_12 小时前
技术发展的核心规律是「加法打底,减法优化,重构平衡」
人工智能·spring boot·spring·重构
牛奔12 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
寻星探路16 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https