JaCoCo Gradle plugin coverage for Android test code

I am new to testing Gradle and Android, but I have already converted my Android project to build using Gradle.

Now I am trying to test cover an Android project using the Gradle JaCoCo plugin.

I added the following to the build.gradle file:

apply plugin: 'jacoco' 

And when I run "gradle jacocoTestReport" the following error:

 Task 'jacocoTestReport' not found in root project '<project name>'. 

From the documentation, I should also use the 'java' plugin, but it conflicts with the 'android' plugin.

Is there any way around this?

Thanks in advance.

+32
android testing code-coverage gradle jacoco
Aug 21 '13 at 13:06 on
source share
4 answers

This is how I use Jacoco :

 buildscript { repositories { mavenLocal() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.12.+' classpath 'org.robolectric:robolectric-gradle-plugin:0.11.+' } } apply plugin: 'com.android.application' apply plugin: 'robolectric' apply plugin: 'jacoco' android { compileSdkVersion 20 buildToolsVersion "20.0.0" defaultConfig { applicationId "YOUR_PACKAGE_NAME" minSdkVersion 10 targetSdkVersion 20 testHandleProfiling true testFunctionalTest true } buildTypes { debug { testCoverageEnabled false } release { runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } } jacoco { version "0.7.1.201405082137" } packagingOptions { exclude 'META-INF/DEPENDENCIES.txt' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/notice.txt' exclude 'META-INF/license.txt' exclude 'META-INF/dependencies.txt' exclude 'META-INF/LGPL2.1' exclude 'META-INF/services/javax.annotation.processing.Processor' exclude 'LICENSE.txt' } } robolectric { include '**/*Test.class' exclude '**/espresso/**/*.class' maxHeapSize "2048m" } jacoco { toolVersion "0.7.1.201405082137" } // Define coverage source. // If you have rs/aidl etc... add them here. def coverageSourceDirs = [ 'src/main/java', ] task jacocoTestReport(type: JacocoReport, dependsOn: "connectedDebugAndroidTest") { group = "Reporting" description = "Generate Jacoco coverage reports after running tests." reports { xml.enabled = true html.enabled = true } classDirectories = fileTree( dir: './build/intermediates/classes/debug', excludes: ['**/R*.class', '**/*$InjectAdapter.class', '**/*$ModuleAdapter.class', '**/*$ViewInjector*.class' ]) sourceDirectories = files(coverageSourceDirs) executionData = files("$buildDir/jacoco/testDebug.exec") // Bit hacky but fixes https://code.google.com/p/android/issues/detail?id=69174. // We iterate through the compiled .class tree and rename $$ to $. doFirst { new File("$buildDir/intermediates/classes/").eachFileRecurse { file -> if (file.name.contains('$$')) { file.renameTo(file.path.replace('$$', '$')) } } } } dependencies { androidTestCompile('junit:junit:4.11') { exclude module: 'hamcrest-core' } androidTestCompile('org.robolectric:robolectric:2.3') { exclude module: 'classworlds' exclude module: 'maven-artifact' exclude module: 'maven-artifact-manager' exclude module: 'maven-error-diagnostics' exclude module: 'maven-model' exclude module: 'maven-plugin-registry' exclude module: 'maven-profile' exclude module: 'maven-project' exclude module: 'maven-settings' exclude module: 'nekohtml' exclude module: 'plexus-container-default' exclude module: 'plexus-interpolation' exclude module: 'plexus-utils' exclude module: 'wagon-file' exclude module: 'wagon-http-lightweight' exclude module: 'wagon-http-shared' exclude module: 'wagon-provider-api' exclude group: 'com.android.support', module: 'support-v4' } } 

The above code also contains a workaround for https://code.google.com/p/android/issues/detail?id=69174 .

More details: http://chrisjenx.com/gradle-robolectric-jacoco-dagger/

+22
Jun 15 '14 at 15:36
source share

I am using JaCoCo with a project using RoboGuice, Butterknife and Robolectric. I was able to customize it using the @Hieu Rocker solution, however there were some minor flaws, that is, in our project we use aromas and additional tests for these tastes, as well as additional Java code for each of them. We also use different types of assembly. Therefore, the decision to rely on the testDebug task was not enough. Here is my solution: In build.gradle in the application module add

 apply from: '../app/jacoco.gradle' 

Then create the jacoco.gradle file inside the application module with the following contents:

     apply plugin: 'jacoco'

     jacoco {
         toolVersion "0.7.1.201405082137"
     }

     def getFlavorFromVariant (String variantName) {
         def flavorString = variantName.replaceAll (/ (. *) ([AZ]. *) /) {all, flavorName, buildTypeName ->
            flavorName
         }
         return flavorString;
     }

     def getBuildTypeFromVariant (String variantName) {
         def buildTypeString = variantName.replaceAll (/ (. *) ([AZ]. *) /) {all, flavorName, buildTypeName ->
             "$ {buildTypeName.toLowerCase ()}"
         }
         return buildTypeString;
     }

     def getFullTestTaskName (String variantName) {
         return "test $ {variantName.capitalize ()} UnitTest";
     }

     android.applicationVariants.all {variant ->
         def variantName = variant.name;
         def flavorFromVariant = getFlavorFromVariant ("$ {variantName}");
         def buildTypeFromVariant = getBuildTypeFromVariant ("$ {variantName}");
         def testTaskName = getFullTestTaskName ("$ {variantName}")

         task ("jacoco $ {variantName.capitalize ()} TestReport", type: JacocoReport, dependsOn: testTaskName) {
             group = "Reporting"
             description = "Generate JaCoCo coverage reports after running tests for variant: $ {variantName}."
             reports {
                 xml.enabled = true
                 html.enabled = true
             }

             classDirectories = fileTree (
                     dir: "./build/intermediates/classes/${flavorFromVariant}/${buildTypeFromVariant}",
                     excludes: ['** / R * .class',
                                '** / * $ InjectAdapter.class',
                                '** / * $ ModuleAdapter.class',
                                '** / * $ ViewInjector * .class'
                     ]
             )

             logger.info ("Configuring JaCoCo for flavor: $ {flavorFromVariant}, buildType: $ {buildTypeFromVariant}, task: $ {testTaskName}");

             def coverageSourceDirs = [
                     '../app/src/main/java',
                     "../app/src/${flavorFromVariantasket/java"
             ]
             sourceDirectories = files (coverageSourceDirs)
             executionData = files ("$ buildDir / jacoco / $ {testTaskName} .exec")
             // Bit hacky but fixes https://code.google.com/p/android/issues/detail?id=69174.
             // We iterate through the compiled .class tree and rename $$ to $.
             doFirst {
                 new File ("$ buildDir / intermediates / classes /"). eachFileRecurse {file ->
                     if (file.name.contains ('$$')) {
                         file.renameTo (file.path.replace ('$$', '$'))
                     }
                 }
             }
         }
     }

You can execute it from the command line as follows:

 .gradlew jacocoFlavor1DebugTestReport 

or

 .gradlew jacocoOtherflavorPrereleaseTestReport 

In our project, we use the agreement not to use an uppercase letter inside the names of the flavor and type of assembly, but if your project does not comply with this agreement, you can simply change the functions getFlavorFromVariant (..) and getBuildTypeFromVariant (..)

Hope this helps someone

+5
Jun 16 '15 at 10:05
source share

You can use this Gradle plugin: https://github.com/arturdm/jacoco-android-gradle-plugin

The answer here is a little bit more https://stackoverflow.com/a/166269/2126 .

0
Sep 14 '15 at 7:22
source share

You tried to add the following:

 jacocoTestReport { group = "Reporting" description = "Generate Jacoco coverage reports after running tests." additionalSourceDirs = files(sourceSets.main.allJava.srcDirs) } 

And then instead of running ./gradlew jacocoTestReport do ./gradlew test jacocoTestReport .

If all goes well, test results should be found in build/reports/jacoco/test/html/index.html .

-3
Dec 11 '13 at 16:40
source share



All Articles