Powermock and sonar jacoco的覆盖率不兼容问题解决 1

我们的系统一直使用Powermock做unit test的mock实现,之前就发现了Powermock在sonar的jacoco的测试覆盖率非常的低,所以我们一直使用cobertura作为我们的sonar测试覆盖率工具,在maven pom文件中使用cobertura的配置如下:

<properties>
....
<!-- define the plugin in sonar, not require after sonar 4.5 -->
<sonar.java.coveragePlugin>cobertura</sonar.java.coveragePlugin>
<!-- report path -->
<sonar.cobertura.reportPath>target/site/cobertura/cobertura.xml</sonar.cobertura.reportPath>
</properties>
<!-- plugin -->
  <plugin> 
                <groupId>org.codehaus.mojo</groupId> 
                <artifactId>cobertura-maven-plugin</artifactId> 
                <version>2.6</version> 
                <configuration> 
                    <formats> 
                    <!-- generate xml report -->
                        <format>xml</format> 
                    </formats> 
                    <instrumentation>
                       <!-- ignore generated code -->
                        <ignore>com.cloud.generated.*</ignore>
                    </instrumentation>
                </configuration> 
                <executions> 
                    <execution> 
                        <id>generate-report</id>
                        <phase>prepare-package</phase>
                        <goals> 
                            <goal>cobertura</goal>  
                        </goals> 
                    </execution> 
                </executions> 
            </plugin> 

这样在package phase就可以在sit/cobertura下看到cobertura的report,执行mvn sonar:sonar就可以扫描cobertura的结果做为test覆盖率。
Note1: sonar server必须安装了支持cobertura结果分析的plugin。
Note2:cobertura会额外多run一次test,在测试用例耗时不长的时候是件好事情,在测试失败的时候可以方便排查是否是cobertura instrument对测试产生了影响。

这一次公司系统环境迁移到新的sonar环境,就不再支持cobertura的配置,所以我们被迫需要转到jacoco测试覆盖率,可是Powermock和jacoco动态测试覆盖率实在不堪入目。我们在网上调查,发现有2种解决方案:
1. 静态Jacoco, offline instrument
2. Powermock Agent

这里先说第一种offline instrument,完整例子可以参考:http://www.eclemma.org/jacoco/trunk/doc/examples/build/pom-offline.xml
这里说说我用到的实现:

<properties>
....
<jacoco.version>0.7.8-SNAPSHOT</jacoco.version>
<!-- define ut/it report path, the same in our system due to sonar version is too old and doesn't support seperated it report-->
<sonar.jacoco.reportPath>${project.build.directory}/jacoco.exec</sonar.jacoco.reportPath>
<sonar.jacoco.itReportPath>${project.build.directory}/jacoco.exec</sonar.jacoco.itReportPath>
<!-- jacoco agent path for dymanic/static instrument-->
<sonar.jacoco.jar>${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar</sonar.jacoco.jar>
<!-- parameter used to control the instrument process, instrument for offline should only be used for ci phase not for loadbuild and package release -->
<jacoco.skip.instrument>true</jacoco.skip.instrument>
</properties>
<!-- include jacoco agent for instrument -->
<dependency>
<!--  must be on the classpath  -->
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<classifier>runtime</classifier>
<version>${jacoco.version}</version>
<scope>test</scope>
</dependency>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<configuration>
  <excludes>
      <exclude>com.cloud.generated.*</exclude>
  </excludes>
  <skip>${jacoco.skip.instrument}</skip>
</configuration>
<executions>
<execution>
<id>default-instrument</id>
<goals>
<goal>instrument</goal>
</goals>
</execution>
<execution>
<id>default-restore-instrumented-classes</id>
<goals>
<goal>restore-instrumented-classes</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.13</version>
<configuration>
<argLine>-XX:-UseSplitVerifier -javaagent:${sonar.jacoco.jar}=destfile=${sonar.jacoco.reportPath,includes=com.cloud.codes}</argLine>
<excludes>
  <exclude>**/*IntegerationTest.java</exclude>
</configuration>
</plugin>
</plugins>

这种实现的问题主要在于支持不够,offline instrument在我们的系统测试过程中对powermockito和openjpa的支持很差,只好放弃选择方案2。方案二的实现在下一次的blog中细说。

阅读更多
换一批

没有更多推荐了,返回首页