Java变更行单元测试覆盖率

概述

Java应用代码的单元测试覆盖率工具Jacoco已经非常成熟及完善了。对于历史的Java项目很多都是没有单元测试的,往往在新的在迭代的过程中都希望能有变更代码行的单元测试覆盖率,从而提高迭代质量。

本文介绍怎么基于jacoco和maven构建变更行单元测试覆盖率报告。对于全量单测覆盖率报告怎么使用可以参考Jacoco官方文档

获取变更行

要构建变更行测试覆盖率,那么首先我们要定位出源代码的变更文件和对应变更行号。

  1. 获取变更文件列表
git diff --name-status  ${baseCommintId} ${currentCommintId}

在这里插入图片描述

解析以上命令行结果可以获得变更文件列表
3. 获取文件变更行明细和行号

git diff -U100000 --cc -W  ${baseCommintId} ${currentCommintId} ${filePath}

在这里插入图片描述

解析返回结果,能够得到对应文件的变更行行号。

生成变更行覆盖率报告

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bCDW1Yks-1617193335708)(http://pfp.ps.netease.com/kmspvt/file/605d392c68d86415a7b4db15iZc1vgE101?sign=1gcBVlZuzh3ANY0RcdajnZur0d0=&expire=1617211329)]

JaCoCo 的注入逻辑用的是 ASM 库,都是基于JVM指令注入,比较复杂。我们用了一个比较快速简单的方式:前面生成全量覆盖率数据的流程不变,只对解析exec 文件生成报告做改造,过滤掉非变更行的行号,生成我们所需要的增量覆盖率模型。参考实现详情-Github

最佳实践

对于现在的应用,大部分都是基于Maven的多模块应用。多模块配置官方推荐

  1. 应用多模块
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sLcEBucp-1617193335709)(http://pfp.ps.netease.com/kmspvt/file/6061d0518c5674448505d3df3kjK7X8a01?sign=XNds4XHlo-ZCBDBsr3DmafK02t4=&expire=1617211329)]

多模块示例说明

  • demo-api 是应用的基础api
  • demo-service 是应用的核心业务处理模块,依赖api
  • demo-app 是应用的最终运行,依赖service
  • demo-build是独立模块,用于生成report
  1. root应用的pom.xml配置

在根pom里面设置jacoco的agent插装及单模块的测试覆盖率报告

<?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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>jacoco_demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>demo-service</module>
        <module>demo-build</module>
        <module>demo-api</module>
        <module>demo-app</module>
    </modules>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <jacoco.version>0.8.6-diff-20210324</jacoco.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.version}</version>
                <configuration>
                    <includes>
                        <include>com/demo/**/*</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <id>prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
  1. 各子模块配置

子模块会继承root模块的配置,无需特殊配置

  1. build模块配置

build模块需要聚合各个子模块的测试报告,切生成变更行的覆盖率报告
build模块需要依赖所有的子模块
build模块需要配置git的基础commitId: mvn.git.base.commit

<?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>jacoco_demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>demo-build</artifactId>

    <properties>
        <mvn.git.base.commit>36a2****338a</mvn.git.base.commit>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>demo-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>demo-app</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>demo-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.version}</version>
                <executions>
                    &lt;-- 各模块全量覆盖率聚合报告 -->
                    <execution>
                        <id>report-aggregate</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report-aggregate</goal>
                        </goals>
                    </execution>
                    
                    &lt;-- 各模块增量覆盖率聚合报告 -->
                    <execution>
                        <id>report-aggregate-diff</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report-aggregate-diff</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
  1. 构建及单元测试

在根目录构建单元测试,各个子模块会生成各自模块的全量单元测试覆盖率
build模块会生成全量模块的聚合单元测试覆盖率,且会生成增量的覆盖率

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t4G7qN76-1617193335709)(http://pfp.ps.netease.com/kmspvt/file/606290eb68d864336b6a794eY9Ul1UIv01?sign=6KgVr-S6IxjGU5DyNOdZ4MyymqQ=&expire=1617211329)]

jacoco-aggregate-diff/index.html 只看行覆盖率,其他的列忽略
jacoco-aggragate/index.html 全量代码覆盖率

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PyikW6sd-1617193335710)(http://pfp.ps.netease.com/kmspvt/file/6062c48b8c5674c09a54dffdBwo0Yake01?sign=JsyKLPlS-BXnz9d_pLAFjLh9HdI=&expire=1617211329)]

后记

基于git和jaccoco的maven插件,我们能获取代码变更行的单元测试覆盖率。对于历史悠久且无单元测试的Java应用迭代可以尽量的控制增量代码单测的规范要求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值