Unable to get Jacoco to work with Powermockito using offline instrumentation

MandyW picture MandyW · Jun 1, 2014 · Viewed 35.4k times · Source

Given that Jacoco doesn't play nicely with PowerMockito when instrumenting "on the fly", I've been trying to configure offline instrumentation in the hope this will give me proper unit test coverage for classes that use PowerMockito.

I've setup my pom as below but I still get zero % coverage on my test class. Any help much appreciated as it's driving me slowly bonkers!

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>mandy</groupId>
    <artifactId>jacoco-test</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>jacoco-test Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <properties>
        <powermock.version>1.5.4</powermock.version>
        <jacoco.version>0.7.1.201405082137</jacoco.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.jacoco</groupId>
            <artifactId>org.jacoco.agent</artifactId>
            <classifier>runtime</classifier>
            <version>${jacoco.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.version}</version>
                <executions>
                    <execution>
                        <id>instrument</id>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>instrument</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>restore-report</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>restore-instrumented-classes</goal>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.17</version>
                <configuration>
                    <!--<argLine>${argLine}</argLine>-->
                    <systemPropertyVariables>
                        <!-- JaCoCo runtime must know where to dump coverage: -->
                        <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
        </plugins>
        <finalName>jacoco-test</finalName>
    </build>
</project>

here is my class under test:

public class Utils {

    private Utils() {

    }

    public static String say(String s) {
        return "hello:"+s;
    }
}

here is my test:

@RunWith(PowerMockRunner.class)

@PrepareOnlyThisForTest(Utils.class)
@PowerMockIgnore("org.jacoco.agent.rt.*")
public class UtilsTest {

    @Test
    public void testSay() throws Exception {
        PowerMockito.mockStatic(Utils.class);
        Mockito.when(Utils.say(Mockito.anyString())).thenReturn("hello:mandy");
        assertEquals("hello:mandy", Utils.say("sid"));
    }

}

I run mvn clean install which generates the jacoco.exe

Coverage report (generated from jacoco.exec using an ant script ):-

Coverage report

Answer

gce picture gce · Jan 4, 2015

This pom worked for me:

 <build>
    <finalName>final-name</finalName>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.18.1</version>
            <configuration>
                <systemPropertyVariables>
                    <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
                </systemPropertyVariables>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.7.2.201409121644</version>
            <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>
    </plugins>
</build>

See this link.