I have a largish Maven multi-module project build. I'm starting with all of our tests using PowerMock, and using Jacoco 0.7.8 and offline instrumentation.
Despite the fact that these are called "unit tests", the tests for classes in one module do call significant code in other modules. As a result, when we view the generated reports, we see the coverage for the classes in the same module as the test, but we don't see coverage for classes in other modules that were executed during the test.
My ASSUMPTION is that if I'm able to change this to use online instrumentation, the resulting coverage report would include the classes from other modules outside of the current module.
So, I set about fixing the one detail in our CUTs (class under test) that required the use of PowerMock instead of Mockito (that part was pretty simple). I fixed this one by one in each test and corresponding CUT, but for now I've only made these changes in a single module in the larger build. I verified that the tests work, and that I can see interactive coverage with EclEmma (another limitation of PowerMock).
The jacoco-maven-plugin is configured in the parent pom that is used by all of the child modules, to presently use offline instrumentation. Eventually, I'm going to change the config in this parent pom to use online instrumentation, but I've decided to leave that there for now and override the config in each module that I've done the conversion in, so that that module uses online instrumentation. I believe I've done that "properly", although I had to use a hack to override the executions list in the child module (remember I'm going to be deleting these once all of them are converted).
When I run the build ("clean install
"), I see it do "prepare-agent
", printing the resulting "argLine
" value, then later on surefire executes, then the "report
" goal executes, printing the path to the jacoco.exec
file, and I see that it says "Analyzed bundle 'my-module-name' with 1 classes
". That seems indicative of a problem.
As the build was now complete, I then opened the "target/site/jacoco/index.html
" file in my browser, and I found that it only included coverage for the present module, and only the single class.
What was also curious is that I superficially inspected the generated "jacoco.exec
" file. I noticed that it was definitely larger than I was used to seeing from other modules still using offline instrumentation. I don't have any way to interpret the format of the file, but I did try to simply "cat
" the file, just to see what I can see. I saw strings that represented class names in other modules that my tests are executing.
So, it seems like online instrumentation is at least recording data for classes in other modules, but the resulting report doesn't show that.
Is it possible to get this coverage?
The following is an excerpt from the "effective-pom" output:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.8</version>
<executions>
<execution>
<id>default-instrument</id>
<phase>none</phase>
<goals>
<goal>instrument</goal>
</goals>
</execution>
<execution>
<id>default-restore-instrumented-classes</id>
<phase>none</phase>
<goals>
<goal>restore-instrumented-classes</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<executions>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<argLine>@{argLine} -Xmx1024m</argLine>
<includes>
<include>**/*Test.java</include>
</includes>
<systemPropertyVariables>
<running-unit-test>true</running-unit-test>
<jacoco-agent.destfile>...\target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
<configuration>
<argLine>@{argLine} -Xmx1024m</argLine>
<includes>
<include>**/*Test.java</include>
</includes>
<systemPropertyVariables>
<running-unit-test>true</running-unit-test>
<jacoco-agent.destfile>...\target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>
Notice that the executions used for offline instrumentation have phase "none
", so they aren't used, and I'm also setting the "jacoco-agent.destfile
" property, which is only used for offline instrumentation.