在maven 的项目中使用cobertura的插件来生成java代码覆盖率的报告,但实际使用中,经常会出现出现报告的值全部 0%,特此文档来说明如何解决该问题。
所有的出现覆盖率为0%的问题均与运行单元测试的插件surefire有关,出现的各种问题均是由于该插件的设置forkcount与reuseForks所影响。
如果出现上述问题,请根据以下的说明与要求来配置surefire插件。
surefire插件官方说明: https://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html
情况1:cobertura插件的bug引起,当maven-surefire-plugin中的配置项forkconut为0时,第一次产生报告时就会导致报告为0.
bug url: http://jira.codehaus.org/browse/MCOBERTURA-70
解决方案:
1. 运行两次 mvn cobertura:cobertura命令, 在jenkins中就是配置运行两次该命令。
2. 设置forkcount = 1, 修改参照:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>x.x.x</version>
<configuration>
<forkCount>1</forkCount>
<reuseForks>true</reuseForks>
</configuration>
</plugin>
PS:
1.此为默认配置,直接从adq-parent或直接使用该插件就为该值。
2.另外关于forkcount>0 设置可能导致单元测试运行在多个线程上而导致不是顺序执行的问题,我查询了官网的说明,原文为:
The default setting is forkCount=1/reuseForks=true, which means that Surefire creates one new JVM process to execute all tests in one maven module.
所以,如果项目中只有一个模块的话,所有的测试应该运行在同一个线程中的,所以设置为1也是可以的。
情况2: 当单元测试用例的内容较多或引用较多的外部lib,就可能会引起插件cobertura运行时出现内存溢出的错误(在日志中会有java.lang.OutOfMemoryError错误),而导致写代码覆盖率数据失败。Edit解决方案:首先需要说明该种情况在日志中会有OOM的错误。
1. 修改reuseForks = false, 注意此时surefire会为每个测试类启动一个独立JVM来运行单元测试,虽然避免了问题,但是如果单元测试之间有依赖关系的话就不能这样解决。另外这样也会导致运行测试的时间大大增加, 修改参照:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>x.x.x</version>
<configuration>
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
</configuration>
</plugin>
2. 如果第一种解决方法不适用的话,可以使用此种方法,为启动的JVM增加启动参数,-Xms512m -Xmx1024m -XX:MaxPermSize=128m, 设置启动内存同样能解决。注意在JDK1.8中,MaxPermSize已经被删除,并且引入了一种新的机制,应该不会再出现此类问题,所以如果修改了该值,JDK升级至1.8后请删除, 以下为修改的参照:
<groupid>org.apache.maven.plugins</groupId>
<artifactid>maven-surefire-plugin</artifactId>
<version>版本看情况吧~</version>
<configuration>
<argLine>-Xms512m -Xmx1024m -XX:MaxPermSize=128m</argLine>
</configuration>