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

6

26

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?

Schrecklichkeit answered 4/11, 2015 at 9:13 Comment(0)
E
18

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
Exultant answered 11/11, 2015 at 18:20 Comment(1)
In addition to this answer, I had similar problem, but with sonarqube task, because my project is compiled with Java 8, jacoco test report is also generated with Java 8 and Sonarqube report is created with Java 11. I had to invoke sonarqube as follows: ./gradlew sonarqube -x compileJava -x processResources -x classes -x jacocoTestReport -x compileTestJava -x test to avoid the error.Tamarau
W
3

I ran into this when trying to run the jacocoTestReport task separate from my test task—not different Java versions, just stale classes.

One workaround is to make sure you get a fresh build and a fresh test run:

$ gradle clean && gradle test && gradle jacocoTestReport

Another is to create a composite task that runs test and jacocoTestReport in order. In your build.gradle:

task coverage {
  dependsOn 'test'
  dependsOn 'jacocoTestReport'
  tasks.findByName('jacocoTestReport').mustRunAfter('test')
}

I'm new to JaCoCo, and I feel like this should be easier, but this worked for me.

Wiersma answered 5/6, 2018 at 18:37 Comment(1)
Tried it as well, but does not work. I'm stuck with the issue on my open source library: github.com/GroupeMINASTE/Makth/issues/1Hin
C
3

If you are using IntelliJ + Maven, try this

Go to File --> Invalidate Caches/Restart

Churchwarden answered 19/1, 2020 at 13:32 Comment(0)
M
0

Sometimes it happens when you run mvn jacoco:report before you run a mvn clean install or mvn clean package.

When this happens Jacoco is referring to a old version of the bytecodes and bytecode of the class files are now changed. Thats when we got build the project again.

So make sure to do package/install before you try for jacoco.

Millett answered 30/8, 2021 at 16:31 Comment(2)
Please provide additional details in your answer. As it's currently written, it's hard to understand your solution.Regulus
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker.Fiume
B
0

Please configure offline instrumentation so that unit test coverage for classes that use PowerMockito should be reflected as follows

    <build>
                <plugins>
                  <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <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>prepare-agent</id>
                    <goals>
                      <goal>prepare-agent</goal>
                    </goals>     
                      </execution>
                      <execution>
                    <id>report</id>   
                    <goals>
                      <goal>report</goal>
                    </goals>
                      </execution>
                    </executions>
                  </plugin>
                </plugins>
                  </build>
Bramblett answered 11/10, 2021 at 11:56 Comment(0)
P
0

I had the same issue,

For me, I just tried the mvn clean install and it worked.

mvn clean install
Pontius answered 8/8, 2023 at 9:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.