6
votes

I'm trying to make jacoco create a code coverage report for my android test project. I have the following in build.gradle:

apply plugin: 'com.android.application'
apply plugin: 'jacoco'
...
jacoco {
    toolVersion = "0.7.1.201405082137"
}
...
android {
    buildTypes {
        release {
        }
        debug {
            testCoverageEnabled true
        }
    }
}

when I run gradlew -i createDebugCoverageReport, I get a coverage report, but it's empty. the end of the gradle execution is as follows:

:androidTest:connectedAndroidTest (Thread[main,5,main]) completed. Took 2 mins 36.951 secs.
:androidTest:createDebugCoverageReport (Thread[main,5,main]) started.
:androidTest:createDebugCoverageReport
Executing task ':androidTest:createDebugCoverageReport' (up-to-date check took 0.006 secs) due to:
  Output file /home/akos/src/androidTest/build/outputs/reports/coverage/debug has changed.
  Output file /home/akos/src/androidTest/build/outputs/reports/coverage/debug/index.html has been removed.
  Output file /home/akos/src/androidTest/build/outputs/reports/coverage/debug/.resources/package.gif has been removed.
[ant:reportWithJacoco] Loading execution data file /home/akos/src/androidTest/build/outputs/code-coverage/connected/coverage.ec
[ant:reportWithJacoco] Writing bundle 'debug' with 3 classes
:androidTest:createDebugCoverageReport (Thread[main,5,main]) completed. Took 0.215 secs.

BUILD SUCCESSFUL

Total time: 4 mins 53.467 secs

and indeed, the coverage.ec file referenced above is empty (of 0 length)

in the directory build/intermediates/coverage-instrumented-classes/ , I seem to have the instrumented class files

this is with gradle 2.1

what am I doing wrong?

8
Does your project structure following Gradle structure.. if you src code in src/java or src/main/java? Where are you defining the location for .exec file (what's .ec)?AKS
it's not the gradle structure, but I'm defining them in the build file. maybe I'm not doing it good enough. this is what I have: sourceSets { androidTest { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['res'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } } and same for 'main' in sourceSetsÁkos Maróy
i hope Peter N can shed some light on this.AKS
Ákos Maróy, did you find a solution for your problem? I am also facing the same issue. Please help if you have a solutionRames Palanisamy

8 Answers

6
votes

Try to generate the debug coverage report using Nexus device (5 or 5x), it will works perfectly. I was facing same issue with Samsung devices (coverage.ec is empty) but after that I run it with Nexus 5x and everything was working fine.

1
votes

There's a problem in the Android Gradle Plugin 0.14.0 that generates an empty coverage.ec file. It's known and was fixed in a branch but doesn't seem to have made it out to the public yet: https://code.google.com/p/android/issues/detail?id=78556

On the other hand, a lovely workaround template project for Android Studio can be found here using Jacoco and RoboElectric: https://github.com/nenick/android-gradle-template

So you can wait for Google to fix it or use someone else's build library repository, but Android Studio 1.0.0's gradle plugin is useless.

1
votes

Jacoco should be inside of the android closure and the jacoco plugin declaration is not necessary:

apply plugin: 'com.android.application'
...
android {
    buildTypes {
        release {
        }
        debug {
            testCoverageEnabled true
        }
    }
    jacoco {
        toolVersion = "0.7.1.201405082137"
    }
}
1
votes

I use same gradle.build and just enter the command below to terminal. It gave me coverage report and test result as a html page.

$./gradlew createDebugCoverageReport

Another suggestion is ; enter terminal

$./gradlew --gui

it opens a gui window and you can find the correct command.

1
votes

I found a solution to same problem from Jacoco code coverage in Android Studio with flavors. It has example what to do in case coverage.ec is generated instead of testDebug.exec.

  1. I created the jacocoTestReport task.

  2. I executed $./gradlew createDebugCoverageReport which generates the coverage.ec file

  3. After that I executed $./gradlew jacocoTestReport and that creates the HTML.
1
votes

Sometimes due to some security restrictions on the underlying hardware you are unable to get coverage reports. In my case I was using android:sharedUserId="android.uid.system" and due to this it was not picking up any coverage and was giving me an empty file.

So I agree naran that you should try running it on different devices and make sure your app is not using android:sharedUserId="android.uid.system".

0
votes

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.

0
votes

I made an interesting observation. I had the same problem, with the coverage.ec File having a size of 0 bytes. I tried all the answers here as well as these ones:

https://code.google.com/p/android/issues/detail?id=170607

It didn't change anything. My build.gradle file has only these settings to let jacoco work:

apply plugin: 'com.android.application'
apply plugin: 'jacoco'

android {
    ...
buildTypes {
   ...
    debug {
        testCoverageEnabled true
    }
}

...
}

My Android Studio Version is 1.2.2. I have the following gradle settings in "File -> Project Structure":

  • Gradle version: 2.2.1
  • Android Plugin Version: 1.2.3

I tried to run the instrumentation tests with gradlew cC on an Motorola Moto G 4G LTE - Android 4.4.4 with correctly ran the instrumentation tests but with a coverage.ec file having 0 bytes. Today I tried another device: LG Spirit 4G LTE - Android 5.0 and now code coverage works!!! The coverage.ec file has 322 bytes and I see correct html coverage reports.

What I think is that sometimes running gradle with gradlew cC --debug shows that coverage.ec cannot be found on the device and sometimes it shows the file being pulled. But maybe in both situations it cannot be found on the device. So choosing another device can fix the problem. Good luck!