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

A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. Use of any information from my blog posts should be at own risk and I do not hold any liability towards any information misuse or damages caused by following any of my posts.

All content and opinions expressed on this Blog are my own and do not represent the opinions of my employer (Oracle). Use of any information contained in this blog post/article is subject to this disclaimer.
Hi! You can search my blog here ⤵
NOTE: (2022) This Blog is no longer maintained and I will not be answering any emails or comments.

I am now focusing on Atari Gamer.