解决Maven多模块项目test覆盖率统计难题:一篇搞定跨模块汇总

16 阅读2分钟

在Java Spring Boot多模块项目开发中,你是否遇到过这样的痛点:

  • 项目拆分为A、B、C业务模块,单独的test模块负责所有模块的测试用例编写
  • 运行test模块后,只能看到test模块自身的覆盖率,A、B、C模块的覆盖率始终为0
  • 尝试多种配置,要么覆盖率统计失真,要么报告无法生成

本文结合实际项目经验,基于JaCoCo工具,提供一套可直接落地的解决方案,让test模块能精准汇总所有业务模块的覆盖率数据,还能生成清晰的可视化报告。

本文所使用到的技术

  • Java 8
  • Spring Boot 2.X
  • Maven 3.5
  • JaCoCo 0.8.13
  • build-helper-maven-plugin 3.2.0

一、先明确核心问题:为什么多模块覆盖率统计会失效?

很多开发者在多模块项目中配置覆盖率时,容易陷入一个误区:直接在单个模块中配置JaCoCo,忽略了Maven多模块的隔离性。

核心原因是:

模块依赖隔离:Maven中每个模块是独立的构建单元,test模块若未显式依赖A、B、C模块,无法加载其字节码,自然无法统计覆盖率.

解决方案核心思路:Maven插件build-helper-maven-plugin将源代码加入到test项目的编译输出目录

二、前置准备:项目结构说明

先明确本文的项目结构

parent-project (父模块,packaging为pom)
├── A (业务模块A,核心业务逻辑)
├── B (业务模块B,核心业务逻辑)
├── C (业务模块C,核心业务逻辑)
└── test (测试模块,依赖AB、C,存放所有测试用例)

三、JaCoCo配置与覆盖率统计

因为其他模块的单元测试的功能全部移交给了test项目负责,所以不需要使用JaCoCo的report聚合功能。直接再test下引入JaCoCo的插件配置和build-helper-maven-plugin

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <version>3.2.0</version>
            <executions>
                <execution>
                    <id>add-source</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>add-source</goal>
                    </goals>
                    <configuration>
                        <sources>
                            <source>../A/src/main/java</source>
                            <source>../B/src/main/java</source>
                            <source>../C/src/main/java</source>
                        </sources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M7</version>
            <configuration>
                <includes>
                    <include>**/*Test.java</include>
                </includes>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M7</version>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!--        jacoco-maven-plugin-->
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.13</version> <!-- 使用最新稳定版 -->
            <configuration>
                <includes>
                    <include>package/**/*</include> <!-- 需要统计的包名 -->
                </includes>
                <excludes>
                    <exclude>package/test/**/*</exclude> <!-- 排除test项目的包 -->
                </excludes>
            </configuration>
            <executions>
                <!-- 步骤1:准备覆盖率数据收集 -->
                <execution>
                    <id>prepare-agent</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                    <configuration>
                        <destFile>${project.build.directory}/jacoco.exec</destFile>
                    </configuration>
                </execution>
                <!-- 步骤2:执行测试后生成覆盖率报告 -->
                <execution>
                    <id>report</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                </execution>
                <!-- 可选:强制覆盖率达标,不达标则构建失败 -->
                <execution>
                    <id>check</id>
                    <phase>test</phase>
                    <goals>
                        <goal>check</goal>
                    </goals>
                    <configuration>
                        <!-- 统一的覆盖率阈值(可根据团队需求调整) -->
                        <rules>
                            <rule>
                                <element>BUNDLE</element>
                                <limits>
                                    <limit>
                                        <counter>LINE</counter>
                                        <value>COVEREDRATIO</value>
                                        <minimum>85%</minimum>
                                    </limit>
                                    <limit>
                                        <counter>BRANCH</counter>
                                        <value>COVEREDRATIO</value>
                                        <minimum>80%</minimum>
                                    </limit>
                                    <limit>
                                        <counter>METHOD</counter>
                                        <value>COVEREDRATIO</value>
                                        <minimum>85%</minimum>
                                    </limit>
                                </limits>
                            </rule>
                        </rules>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

四、查看与分析覆盖率总结

执行命令 mvn clean test jacoco:report

可以看到target目录下生成了其他模块的源码,这样jacoco就可以统计到这些代码的覆盖率了。

image.png

查看JaCoCo生成的覆盖率报告(target/site/index.html)

image.png