Cobertura del código de prueba de Android con el plugin JaCoCo Gradle

Soy nuevo en las pruebas de Gradle y Android, pero ya he convertido mi proyecto de Android para comstackr con Gradle.

Ahora estoy intentando realizar una cobertura de prueba de un proyecto de Android con el complemento JaCoCo de Gradle.

He agregado lo siguiente a mi archivo build.gradle:

apply plugin: 'jacoco' 

Y cuando ejecuto “gradle jacocoTestReport” aparece el siguiente error:

 Task 'jacocoTestReport' not found in root project ''. 

De la documentación se supone que también debo aplicar el plugin ‘java’, pero entra en conflicto con el plugin ‘android‘.

¿Hay alguna forma de evitar esto?

Gracias por adelantado.

Así es como estoy usando 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' } } 

El código anterior también contiene una solución para https://code.google.com/p/android/issues/detail?id=69174 .

Más detalles: http://chrisjenx.com/gradle-robolectric-jacoco-dagger/

Estoy usando JaCoCo con un proyecto que usa RoboGuice, Butterknife y Robolectric. Pude configurarlo utilizando la solución de @Hieu Rocker, sin embargo, hubo algunos inconvenientes menores, es decir, en nuestro proyecto usamos sabores y tenemos algunas pruebas adicionales para esos sabores, así como código extra de Java para cada uno de ellos. También utilizamos diferentes tipos de comstackción. Por lo tanto, una solución para confiar en la tarea “testDebug” no era lo suficientemente buena. Aquí está mi solución: en el módulo build.gradle in app add

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

Luego crea un archivo jacoco.gradle dentro del módulo de la aplicación con el siguiente contenido:


     aplicar el complemento: 'jacoco'

     jacoco {
         toolVersion "0.7.1.201405082137"
     }

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

     def getBuildTypeFromVariant (String variantName) {
         def buildTypeString = variantName.replaceAll (/ (. *) ([AZ]. *) /) {all, flavorName, buildTypeName ->
             "$ {buildTypeName.toLowerCase ()}"
         }
         devuelve 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", escriba: JacocoReport, dependsOn: testTaskName) {
             group = "Informes"
             description = "Generar informes de cobertura de JaCoCo después de ejecutar pruebas para la variante: $ {variantName}."
             informes {
                 xml.enabled = true
                 html.enabled = true
             }

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

             logger.info ("Configuración de JaCoCo para sabor: $ {flavorFromVariant}, buildType: $ {buildTypeFromVariant}, task: $ {testTaskName}");

             def coverageSourceDirs = [
                     '../app/src/main/java',
                     "../app/src/${flavorFromVariant}/java"
             ]
             sourceDirectories = archivos (coverageSourceDirs)
             executionData = files ("$ dirDir / jacoco / $ {testTaskName} .exec")
             // Bit hacky pero corrige https://code.google.com/p/android/issues/detail?id=69174.
             // iteramos a través del árbol comstackdo .class y cambiamos el nombre de $$ a $.
             hacer primero {
                 nuevo archivo ("$ buildDir / intermedios / clases /"). eachFileRecurse {archivo ->
                     if (file.name.contains ('$$')) {
                         file.renameTo (file.path.replace ('$$', '$'))
                     }
                 }
             }
         }
     }

Puede ejecutarlo desde línea de comandos de esta manera:

 .gradlew jacocoFlavor1DebugTestReport 

o

 .gradlew jacocoOtherflavorPrereleaseTestReport 

En nuestro proyecto utilizamos una convención para no utilizar letras mayúsculas dentro de los nombres de tipo de comstackción y sabor, pero si su proyecto no sigue esta convención, simplemente puede cambiar las funciones getFlavorFromVariant (..) y getBuildTypeFromVariant (..)

Espero que esto ayude a alguien

Puede intentar usar este plugin de Gradle: https://github.com/arturdm/jacoco-android-gradle-plugin

Hay un poco más en la respuesta aquí https://stackoverflow.com/a/32572259/1711454 .

¿Intentó agregar lo siguiente?

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

Y luego, en lugar de ejecutar ./gradlew jacocoTestReport ejecutar ./gradlew test jacocoTestReport .

Si todo va bien, debe encontrar los resultados de la prueba en build/reports/jacoco/test/html/index.html .