Maven Verify执行Jacoco代码覆盖率始终为0%的问题求助
mvn verify时Jacoco覆盖率显示0%,但IDE中JUnit覆盖率超90% 执行mvn verify时Jacoco返回代码覆盖率为0%,但IDE里JUnit测试覆盖率超过90%,且所有测试运行正常。从旧项目导入了测试类和对应业务类,当前使用Maven 3.9.9,旧项目中Maven能正常返回准确覆盖率,怀疑是版本或pom.xml配置存在问题。
终端执行日志
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 14.39 s -- in uk.ac.rhul.cs2800.Cw2ApplicationTests [INFO] Running uk.ac.rhul.cs2800.model.StudentTest [INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.044 s -- in uk.ac.rhul.cs2800.model.StudentTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 9, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] [INFO] --- jacoco:0.8.12:report (report) @ CW2 --- [INFO] Loading execution data file C:\Users\readh\workspace\cs2800\cw2\target\jacoco.exec [INFO] Analyzed bundle 'CW2' with 7 classes [INFO] [INFO] --- jar:3.4.2:jar (default-jar) @ CW2 --- [INFO] Building jar: C:\Users\readh\workspace\cs2800\cw2\target\CW2-0.0.1-SNAPSHOT.jar [INFO] [INFO] --- spring-boot:3.3.6:repackage (repackage) @ CW2 --- [INFO] Replacing main artifact C:\Users\readh\workspace\cs2800\cw2\target\CW2-0.0.1-SNAPSHOT.jar with repackaged archive, adding nested dependencies in BOOT-INF/. [INFO] The original artifact has been renamed to C:\Users\readh\workspace\cs2800\cw2\target\CW2-0.0.1-SNAPSHOT.jar.original [INFO] [INFO] --- jacoco:0.8.12:check (jacoco-check) @ CW2 --- [INFO] Loading execution data file C:\Users\readh\workspace\cs2800\cw2\target\jacoco.exec [INFO] Analyzed bundle 'CW2' with 7 classes [WARNING] Rule violated for package uk.ac.rhul.cs2800.repository: lines covered ratio is 0.0, but expected minimum is 0.9 [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 30.333 s [INFO] Finished at: 2024-12-10T17:50:51+02:00 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.jacoco:jacoco-maven-plugin:0.8.12:check (jacoco-check) on project CW2: Coverage checks have not been met. See log for details. -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
pom.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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.6</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>uk.ac.rhul.cs2800</groupId> <artifactId>CW2</artifactId> <version>0.0.1-SNAPSHOT</version> <name>CW2</name> <description>Demo project for Spring Boot</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>3.4.0</version> <configuration> <configLocation>google_checks.xml</configLocation> <consoleOutput>true</consoleOutput> <failsOnError>true</failsOnError> <violationSeverity>warning</violationSeverity> </configuration> </plugin> <plugin> <groupId>com.github.spotbugs</groupId> <artifactId>spotbugs-maven-plugin</artifactId> <version>4.8.6.0</version> <configuration> <threshold>High</threshold> </configuration> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.12</version> <configuration> <excludes> <exclude>**/Cw2Application*</exclude> </excludes> </configuration> <executions> <execution> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>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.9</minimum> </limit> </limits> </rule> </rules> </configuration> </execution> </executions> </plugin> </plugins> </build> <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> <version>3.20.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> <version>3.6.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>3.5.0</version> <configuration> <configLocation>google_checks.xml</configLocation> <failsOnError>true</failsOnError> <violationSeverity>warning</violationSeverity> </configuration> <reportSets> <reportSet> <reports> <report>checkstyle</report> </reports> </reportSet> </reportSets> </plugin> <plugin> <groupId>com.github.spotbugs</groupId> <artifactId>spotbugs-maven-plugin</artifactId> <version>4.8.6.0</version> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.12</version> <configuration> <excludes> <exclude>**/Cw2Application*</exclude> </excludes> </configuration> <reportSets> <reportSet> <reports> <report>report</report> </reports> </reportSet> </reportSets> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>3.10.0</version> <configuration> <doclint>all,-missing</doclint> </configuration> </plugin> </plugins> </reporting> </project>
问题分析与修复方案
核心问题
从日志可见,Jacoco仅分析了7个类,且uk.ac.rhul.cs2800.repository包覆盖率为0。结合Spring Boot项目特性,主要问题是Jacoco的覆盖率采集时机与Spring Boot打包流程冲突,导致Jacoco无法正确读取业务类的执行数据。
具体修复步骤
调整Jacoco的
prepare-agent执行阶段
当前prepare-agent未指定阶段,默认绑定到initialize,可能早于测试类编译。修改为绑定到test-compile阶段,确保测试执行时代码已被插桩:<execution> <id>prepare-agent</id> <phase>test-compile</phase> <goals> <goal>prepare-agent</goal> </goals> </execution>让Jacoco在Spring Boot repackage前完成分析
日志中spring-boot:repackage在Jacoco的check之前执行,会替换原始jar,导致Jacoco分析的是打包后的BOOT-INF内的类,而非编译后的原始类。给Spring Boot插件添加配置,保留原始jar:<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <attach>true</attach> <!-- 保留原始jar作为Maven附属构件 --> </configuration> </plugin>验证测试类与业务类的包路径一致性
确认导入的测试类包路径和对应业务类完全匹配,比如StudentTest对应的Student类是否在uk.ac.rhul.cs2800.model包下,避免测试未正确加载业务类。清理后重新构建
执行mvn clean verify,清除旧的编译产物和覆盖率数据,重新生成正确的jacoco.exec文件。
额外排查点
- 检查
target/jacoco.exec文件大小,若为空则说明测试执行时未采集到覆盖率数据,需检查prepare-agent是否生效。 - 确认Jacoco的
excludes配置未误排除业务类,当前配置仅排除启动类,无问题。
内容的提问来源于stack exchange,提问作者EpicGaia

