Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

We make heavy use of PowerMock in many of our JUnit tests and recently as we switched from Cobertura to JaCoCo something strange happened. Code coverage dropped! There wasn't a reduction in tests so something else must have been at fault.

The configuration for the JaCoCo and Surefire Maven plugins was set up such that on-the-fly instrumentation (via a Java Agent) was being used i.e....
 Maven
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
...
<argLine>@{argLine}</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.8</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<dumpOnExit>true</dumpOnExit>
<output>file</output>
</configuration>
</execution>
<execution>
<id>default-report</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>


That was giving some terrible code coverage results. In certain cases coverage dropped by 80%. It was a lot of red there!
jacoco_1.png


After a bit of research and reading up on PowerMock, I came across this piece of documentation - Code coverage with JaCoCo. Which had this informative line...
...right now there is NO WAY TO USE PowerMock with JaCoCo On-the-fly instrumentation...




Well, boo. There was a way forward. Using offline instrumentation was the solution apparently. This actually simplified some of the Maven plugin configuration as the Surefire plugin didn't need to be configured with the argLine any more. The new JaCoCo configuration now looked like this...
 Maven
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.8</version>
<executions>
<execution>
<id>jacoco-instrument</id>
<goals>
<goal>instrument</goal>
</goals>
</execution>
<execution>
<id>jacoco-restore-instrumented-classes</id>
<goals>
<goal>restore-instrumented-classes</goal>
</goals>
</execution>
<execution>
<id>jacoco-report</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>


Sure enough the coverage report jumped back up to the expected numbers!
jacoco_2.png


As a nice side effect I also noticed that offline instrumentation is significantly faster than on the fly instrumentation. While it took about 2min 20sec to run the build with on the fly instrumentation, offline instrumentation brought this time down to around 50sec.

-i

Use of any information contained in this blog post/article is subject to this disclaimer.
comments powered by Disqus
Other posts you may like...