18
votes

I have a multi-module Android project and I'm seeing a discrepancy between the coverage that jacoco reports and what Sonarqube reports. The project is also a multi-flavor project that generates a lot of different variants. I am using this plugin to help me generate all of the tasks. The tasks generate an individual report for each variant.

When I run my jacoco reports I see this:

jacoco report

When I run the sonar scanner i see this: sonar coverage report

I have some exclusions on my project,but even without them the coverage %s don't match.

I feel like I may not be providing the same bytecode as hinted in this question:

Here is my relevant info: Sonar Version 5.6.

Gradle runner

plugins { id "org.sonarqube" version "2.0.1" }

Sonar config: (on root build.gradle)

sonarqube {
    properties {
        property "sonar.projectKey", "com.xxx.myApp"
        property "sonar.projectName", "Android My App"
        property "sonar.projectVersion", "3.0"
        property "sonar.java.binaries", "build/classes"
        property "sonar.coveragePlugin", "jacoco"
        property "sonar.jacoco.reportMissing.force.zero", "false"
    }
}

Sonar config (on app/build.gradle)

sonarqube {
    properties {
        property "sonar.sources", "src/main/java"
        property "sonar.tests", "src/test/java"
        property "sonar.java.tests", "src/test/java"
        property "sonar.junit.reportsPath", "build/test-results/myAppGoogleMobileDebug"
        property "sonar.java.binaries", "build/intermediates/classes/myAppGoogleMobile/debug"
        property "sonar.jacoco.reportPath", "build/jacoco/testMyAppGoogleMobileDebugUnitTest.exec"
        property "sonar.coverage.exclusions", coverageExclusions

    }
}

Jacoco config on (app/build.gradle)

def coverageExclusions = ['**/AEWatchApp.*', '**/**_Factory.*',
                          '**/QaSettingsActivity.*',
                          'com/aetn/android/tveapps/activities/**',
                          'com/aetn/android/tveapps/test/**',
                          'com/aetn/android/tveapps/app/injection/modules/**',
                          'com/aetn/android/tveapps/app/injection/components/**',
                          'com.aetn.android.tveapps.mock/**',
                          'com/aetn/android/tveapps/databinding/**']


jacocoAndroidUnitTestReport {
    csv.enabled false
    html.enabled true
    xml.enabled true
    excludes += coverageExclusions
}
1

1 Answers

20
votes

As far as I can see branch coverage is the same: 40% in both cases, 15 uncovered.

And comparison of "instructions" (shown in screenshot of JaCoCo report) with anything else is like comparison of apples and oranges - they don't represent the same thing. See http://www.eclemma.org/jacoco/trunk/doc/counters.html about counters that JaCoCo provides. And http://docs.sonarqube.org/display/SONAR/Metric+Definitions about what SonarQube shows. Instructions coverage is presented only in JaCoCo.

"lines" ("27.1%" shown in screenshot of SonarQube) is not the same as "instructions": Single line of code usually contains many bytecode instructions. So for example if in total you have 100 instructions in 10 lines and cover 1 line with 20 instructions, then missed instructions 80%, but missed lines 90%.

So all in all, there is no discrepancy or at least it is not shown on your screenshots.