4

A Github repo with the code used for this question can be found here: https://github.com/thenewmr/UnitTestCoverageExample

We've been having serious issues trying to get a code coverage report via Jacoco generated correctly.

We've followed various guides on the internet including this one from Patrick McLaren that he linked to in his answer to this question.

We've also looked at various questions on stack overflow but no joy so far.

Here's what we have so far (in bullet point form so as not to make this question too long to read):

  • Adding testCoverageEnabled = true to the debug closure created a task called "createDebugCoverageReport"
  • Running this task:

    • Produces a report for our Android tests at: app/build/outputs/reports/androidTests/connected/index.html with an accurate report of test passes and failures etc
    • But an inaccurate coverage report (0% coverage) at: app/build/outputs/reports/coverage/debug/index.html
    • It also produces what appears to be empty coverage data at: app/build/outputs/code-coverage/connected/coverage.ec
  • Now, if we add the following:

    apply plugin: 'jacoco'
    
    //specify which directories should be examined by jacoco
    def coverageSourceDirs = [
            'src/main/java'
    ]
    
    task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug") {
        group = "Reporting"
    
        description = "Generate Jacoco coverage reports"
    
        classDirectories = fileTree(
                dir: 'build/intermediates/classes/debug',
                excludes: ['**/R.class',
                           '**/R$*.class',
                           '**/*$ViewInjector*.*',
                           '**/BuildConfig.*',
                           '**/Manifest*.*']
        )
    
        additionalSourceDirs = files(coverageSourceDirs)
        sourceDirectories = files(coverageSourceDirs)
        executionData = files('build/jacoco/testDebug.exec')
    
        reports {
            xml.enabled = true
            html.enabled = true
        }
    }
    

to the build.gradle file for the app (with or without the bit above) and run jacocoTestReport, we get:

  • A test report for the vanilla Unit tests at: app/build/reports/tests/debug/index.html
  • An accurate code coverage report at app/build/reports/jacoco/jacocoTestReport/html/index.html

So, we get the correct stuff for the vanilla unit tests but not for the Android unit tests.

The blog post mentioned above talks about how to combine the two reports. But it seems it would be pointless if we can’t get the Android test coverage report produced in the first place.

The problem appears to be due to the empty coverage.ec file as mentioned earlier.

This answer says this used to be a bug: https://stackoverflow.com/a/28080713/487812

and this bug report says this problem was fixed: https://code.google.com/p/android/issues/detail?id=78556

But perhaps it's been reintroduced since as a regression? Are we missing something obvious?

Community
  • 1
  • 1
the_new_mr
  • 3,476
  • 5
  • 42
  • 57

2 Answers2

8

Though nius' answer is correct, the info below was the solution to our particular problem.

Turns out that, for some bizarre reason, running the tests on Samsung devices yields empty coverage files. Running the same tests on an emulator or non-Samsung phone produced the desired results.

Including this info here so that people are aware of this.

the_new_mr
  • 3,476
  • 5
  • 42
  • 57
  • I have experienced the same problem with Samsung. I run ./gradlew createDebugCoverageReport and get 0 test coverage when my Samsung S6 is plugged in. Switch to my Droid Turbo, I get the correct results. CMON SAMSUNG ;-) – Ryan Newsom Aug 11 '16 at 21:25
2

Now (Oct 2015) you can use it as android team has fixed the bug.

android {
    ...
    buildTypes {
        debug {
            testCoverageEnabled true
        }
    }
    ...
    dependencies{
        androidTestCompile 'com.android.support.test:runner:0.4.1'
        // Set this dependency to use JUnit 4 rules
        androidTestCompile 'com.android.support.test:rules:0.4.1'
        // Set this dependency to build and run Espresso tests
        androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
        // Espresso-contrib for DatePicker, RecyclerView, Drawer actions, Accessibility checks, CountingIdlingResource
        androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.1'
    }
}

Then just use ./gradlew createDebugCoverageReport. Find the reports in app/build/reports/coverage/debug/index.html.

nius
  • 509
  • 3
  • 12