JUnit本身不统计覆盖率,必须靠Surefire执行测试+JaCoCo插桩采集数据再生成行覆盖率报告;关键在于Maven构建链协同:Surefire需正确运行测试(确认maven-surefire-plugin配置、测试类命名合规、控制台显示Tests run统计),JaCoCo插件须绑定prepare-agent和report两个goal并设置argLine引用jacocoArgLine,最终报告输出至target/site/jacoco/index.html,“Line Coverage”即行覆盖率。

JUnit 本身不统计覆盖率,必须靠 Surefire 执行测试 + JaCoCo 插桩采集数据,再生成行覆盖率报告。关键不是“JUnit 怎么做”,而是整个 Maven 构建链怎么协同。
确保 Surefire 正确运行测试
JaCoCo 要采集数据,前提是测试真被执行了。Surefire 是实际触发 JUnit 测试的插件:
- 确认 pom.xml 中已声明
maven-surefire-plugin(新版 Maven 通常自带,但显式配置更可控) - 测试类命名需符合默认规则:以
Test开头或结尾,或含TestCase;否则 Surefire 会跳过,JaCoCo 就没数据可采 - 运行
mvn test后,检查控制台末尾是否有类似Tests run: 5, Failures: 0, Errors: 0的统计——没有就说明 Surefire 根本没发现测试
用 JaCoCo 插件完成插桩与报告生成
JaCoCo 不依赖 JUnit,它监听 JVM 启动时的字节码加载过程,通过 prepare-agent 注入探针:
- 在 pom.xml 的
<build><plugins>中添加jacoco-maven-plugin,并绑定两个 goal:prepare-agent(在 test 阶段前注入 JVM 参数)report(test 执行后,解析target/jacoco.exec生成 HTML 报告) - 务必让 Surefire 使用 JaCoCo 注入的参数:
在 Surefire 配置中设置<argLine>${jacocoArgLine}</argLine> - 执行命令:
mvn clean test jacoco:report
报告会输出到target/site/jacoco/index.html,打开后“Line Coverage”列即为行覆盖率
识别 JaCoCo 行覆盖率的真实含义
“行覆盖率”指物理代码行是否被至少执行一次,但它有天然局限,别误判为代码缺陷:
立即学习“Java免费学习笔记(深入)”;
- 空的
catch块、只含return;的finally,即使逻辑上不可能进入,JaCoCo 也要求“执行到该行”才算覆盖 - switch 的
default分支,哪怕所有 case 都覆盖了,只要没显式触发 default,这行就标红 - Lombok 生成的 getter/setter 或
@Data方法,源码不可见,JaCoCo 默认跳过——需在插件配置中用<excludes>过滤,避免拉低分母
快速验证和调试常见问题
如果报告里大片红色,大概率不是测试没写,而是链路断了:
- 检查
target/jacoco.exec文件是否存在且非空——不存在说明 JaCoCo 没插桩;为空说明测试根本没执行 - 在 IDEA 中右键运行测试时,确认 Run Configuration 的 Coverage 设置为 “JaCoCo”,并勾选 “Tracing”(尤其对分支多的逻辑)
- Spring Boot 项目要排除启动类(如
*Application.class),否则主类的 main 方法也会计入覆盖率分母,人为压低数值


















