Search code examples
javaandroidgradlepowermockjacoco

Jacoco: For report generation the same class files must be used as at runtime


I have been working on an android project and use roboletric and powermock to do unitTests.

When I run gradle jacocoTestReport, it will show

[ant:jacocoReport] Classes in bundle 'app' do no match with execution data. For report generation the same class files must be used as at runtime.
[ant:jacocoReport] Execution data for class com/my/app/MyClass does not match.

Where I use powermock to mock the static method in Myclass.java

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(MyClass.class)
public class TheTest {

    @Rule
    public PowerMockRule rule = new PowerMockRule();

    @Test
    public void test1() throws Exception {
        PowerMockito.mockStatic(MyClass.class);
        // do something
    }
}

And the build.gradle is shown as follows

apply plugin: 'jacoco'
def coverageSourceDirs = [
         '../app/src/main/java'
]

task jacocoTestReport(type:JacocoReport, dependsOn: "testDebugUnitTest") {
    group = "Reporting"
    description = "Generate Jacoco coverage reports"

    classDirectories = fileTree(
            dir: '../app/build/intermediates/classes/debug',
            excludes: ['**/R.class',
                       '**/R$*.class',
                       '**/*$ViewInjector*.*',
                       '**/BuildConfig.*',
                       '**/Manifest*.*']
    )

    additionalSourceDirs = files(coverageSourceDirs)
    sourceDirectories = files(coverageSourceDirs)
    executionData = files('../app/build/jacoco/testDebugUnitTest.exec')

    reports {
        xml.enabled = true
        html.enabled = true
    }

}

I can still see the coverage report without distortion.

But How to get rid of such warning?


Solution

  • This happens when you are using a Java version X to compile the classes and running the tests (jacoco) but running the jacocoTestReport task (in Gradle), you are using another Java version aka Java Y.

    Are you setting a different JAVA version or using a different Gradle (which is using different JAVA)? You may be getting a partial coverage as when you see this warning/error message about execution data for class xxx/yyy/zzz does not match, that means it'll reflect 0% coverage.

    To fix the following issue:

    [ant:jacocoReport] Classes in bundle 'app' do no match with execution data. For report generation the same class files must be used as at runtime.
    [ant:jacocoReport] Execution data for class com/my/app/MyClass does not match.
    

    Make sure that:

    1. You JAVA version is SAME while running "gradle clean build" or "gradle integrationTest" or "gradle someKindOfnonUnitTest" (behind external container like Tomcat etc) and for generating the coverage report using jacoco using jacocoTestReport task.

    OR if the above doesn't help the,

    1. While running "gradle jacocoTestReport" (assuming you have the valid .exec files for your Unit / NonUnit tests in the workspace), pass some command line switches like shown below.

    For ex:

    gradle clean build 
    gradle ...some..nonUnitTestTask
    

    then

    gradle jacocoTestReport -x test -x testClasses -x compileJava -x classes