Skip to content
h8MyJob edited this page Oct 30, 2018 · 4 revisions

Welcome to the PowerMockJacocoDemo wiki!

This project demonstrates the Powermock/Jacoco issue and provides a gradle android solution.

Problem

The combination of PowerMock and Jacoco can result in fully covered classes being reported as 0% coverage.

In a nutshell (verbatim from a jacoco forum)

  • source file is compiled into non-instrumented class file
  • non-instrumented class file is instrumented (either pre-instrumented offline, or automatically at runtime by Java agent)
  • execution of instrumented classes collected into exec file
  • report decorates source files with information obtained from analysis of exec file and original non-instrumented class files
  • Message "Classes ... do no match with execution data." during generation of report means that class files used for generation of report are not the same as classes prior to instrumentation.

It’s a well-known issue and more can be found at the powermock github PowerMock/Jacoco page. On the jacoco side, more information can be found at Jacoco Class Ids

Solution

Usage

  • The main files in questions are build.gradle, jacoco.gradle, and jacoco_offline.gradle.
  • build.gradle is referencing either jacoco.gradle or jacoco_offline.gradle depending what type of instrumentation desired.
  • While jacoco_offline.gradle is intuitively titled, jacoco.gradle can be seen as jacoco_on_the_fly.gradle. However, we're staying clear of such nomenclature because on-the-fly instrumentation is jacoco's default behavior.

Jacoco On-the-fly Instrumentation

This is jacoco default setup for instrumentation and will reproduce the issue

  1. Ensure that file build.gradle is referencing the jacoco.gradle file. gradle jacoco.gradle selected

  2. Run command gradle clean & gradle jacocoTestReport

  • gradle clean will wipe out any previous gradle execution artifacts
  • gradle jacocoTestRerport will run test and generate jacoco report

Output

  • Notice the two files, Configuration.java & Lamda.java that, do not have the proper execution data. Command Line on-the-fly result

  • Consequently the two files will display as 0% coverage in the jacoco report. jacoco on-the-fly html report

Jacoco Offline Instrumentation

This will run offline instrumentation on the same project

  1. Ensure that file build.gradle is referencing the jacoco_offline.gradle file. build.gradle referencing jacoco_offline.gradle

  2. Run command gradle clean & gradle createOfflineTestCoverageReport & gradle jacocoTestReport

  • gradle clean will wipe out any previous gradle execution artifacts
  • gradle createOfflineTestCoverageReport will create offline instrumentation, change order of classpath, generate .exec file
  • gradle jacocoTestReport will run test and generate jacoco report based on previously generated .exec file
  • Alternatively: gradle jacocoTestReport -x test can be used to skip over some steps possibly covered by gradle createOfflineTestCoverageReport

Output

  • Notice there are no alerts of execution data mismatch jacoco offline command line

  • Notice the increase and accurate coverage for files Configuration.java and Lamda.java in the jacoco html report jacoco html report

Alternative Usage

  • It is possible to run just two tasks: gradle clean & gradle createOfflineTestCoverageReport
  • This is possible because of a snippet of the script html(destdir: "$buildDir.path/reports/jacocoHtml") that is commented
  • That snippet of code needs to be uncommented before usage. However, keep in mind that the script currently does not account for file exclusion -- this is taken care of by jacocoTestReport task.

Reference