如何通过Maven Cargo+Surefire+Jacoco获取Tomcat代码集成测试覆盖率
解决独立Tomcat JVM代码覆盖率的JaCoCo配置方案
我之前也碰到过一模一样的问题——用Cargo启动Tomcat跑集成测试,结果只能拿到测试代码的覆盖率,完全不是我们要的服务端业务代码的数据。下面是我验证过的可行方案,核心是让Tomcat进程被JaCoCo代理追踪,然后在测试结束后导出覆盖率数据:
第一步:配置Cargo插件,让Tomcat启动时加载JaCoCo Agent
你需要在Maven的Cargo插件配置里,给Tomcat的JVM添加JaCoCo agent参数,这样Tomcat运行的代码会被JaCoCo监控。
在你的pom.xml里找到Cargo插件的配置块,加入jvmArgs:
<plugin> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven2-plugin</artifactId> <version>你的Cargo版本</version> <configuration> <container> <containerId>tomcat9x</containerId> <!-- 换成你的Tomcat版本 --> <home>${tomcat.home}</home> </container> <configuration> <properties> <!-- 其他Tomcat配置... --> </properties> </configuration> <deployables> <deployable> <groupId>你的项目groupId</groupId> <artifactId>你的web模块artifactId</artifactId> <type>war</type> </deployable> </deployables> <!-- 关键:添加JaCoCo Agent到Tomcat的JVM参数 --> <jvmArgs> -javaagent:${settings.localRepository}/org/jacoco/jacocoagent/0.8.8/jacocoagent-0.8.8.jar=destfile=${project.build.directory}/jacoco-tomcat.exec,append=true,includes=你的包路径** </jvmArgs> </configuration> </plugin>
这里要注意几个点:
- 替换
jacocoagent的版本为你项目里用的JaCoCo版本 destfile指定Tomcat进程生成的覆盖率数据文件路径,一般放在项目构建目录下includes要设置成你Tomcat里运行的业务代码的包路径(比如com.yourcompany.**),这样只会收集你关心的代码覆盖率,避免无关类干扰
第二步:配置JaCoCo插件,用于生成最终覆盖率报告
接下来需要配置JaCoCo插件,让它在测试结束后,把Tomcat生成的jacoco-tomcat.exec和测试代码的覆盖率数据合并(如果需要的话),然后生成针对业务代码的报告。
在pom.xml里添加JaCoCo插件配置:
<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>你的JaCoCo版本</version> <executions> <!-- 可选:如果需要收集测试代码本身的覆盖率,保留这个execution;否则可以去掉 --> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <!-- 关键:生成覆盖率报告,指定Tomcat的exec文件 --> <execution> <id>report</id> <phase>post-integration-test</phase> <!-- 在集成测试结束后执行 --> <goals> <goal>report</goal> </goals> <configuration> <dataFiles> <!-- 包含Tomcat生成的覆盖率文件 --> <dataFile>${project.build.directory}/jacoco-tomcat.exec</dataFile> <!-- 如果需要合并测试代码的覆盖率,加上这行;否则去掉 --> <dataFile>${project.build.directory}/jacoco.exec</dataFile> </dataFiles> <!-- 指定要生成报告的源代码路径,也就是Tomcat里运行的业务代码 --> <sourceDirectory>../your-web-module/src/main/java</sourceDirectory> <!-- 换成你的web模块源码路径 --> <classDirectory>${project.build.directory}/classes</classDirectory> </configuration> </execution> </executions> </plugin>
第三步:执行流程和注意事项
- 先启动Tomcat并部署应用:
mvn cargo:run(或者用cargo:start后台启动) - 运行集成测试:
mvn verify(或者单独运行集成测试目标,比如mvn failsafe:integration-test) - 测试结束后,JaCoCo会在
${project.build.directory}/site/jacoco下生成HTML格式的覆盖率报告,打开index.html就能看到Tomcat中运行的业务代码的覆盖率数据了
额外提醒几个坑:
- 确保Tomcat启动时JaCoCo agent能正确加载,如果启动报错,检查
javaagent的路径是否正确,或者直接用绝对路径测试 - 如果你的集成测试是单独的模块,要注意路径配置,比如
sourceDirectory要指向web模块的源码,而不是测试模块的 - 如果你用
cargo:stop关闭Tomcat,JaCoCo会自动把覆盖率数据写入destfile;如果是强制杀死进程,可能会导致数据丢失,所以尽量用正常关闭方式
内容的提问来源于stack exchange,提问作者spy
相关产品推荐
相关产品推荐

