Pertanyaan Cakupan kode tes Android dengan plugin JaCoCo Gradle


Saya baru mengenal Gradle dan pengujian Android, tetapi saya sudah mengonversi proyek Android saya untuk dibuat dengan Gradle.

Sekarang saya mencoba melakukan uji cakupan proyek Android dengan plugin Gradle's JaCoCo.

Saya telah menambahkan yang berikut ini ke file build.gradle saya:

apply plugin: 'jacoco'

Dan ketika saya menjalankan "gradle jacocoTestReport", galat berikut:

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

Dari dokumentasi saya seharusnya juga menerapkan plugin 'java' tetapi konflik dengan plugin 'android'.

Apakah ada jalan untuk ini?

Terima kasih sebelumnya.


32
2017-08-21 13:06


asal


Jawaban:


Di sini adalah bagaimana saya menggunakan 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'
  }
}

Kode di atas juga berisi solusi untuk https://code.google.com/p/android/issues/detail?id=69174.

Keterangan lebih lanjut: http://chrisjenx.com/gradle-robolectric-jacoco-dagger/


23
2018-06-15 15:36



Saya menggunakan JaCoCo dengan proyek menggunakan RoboGuice, Butterknife dan Robolectric. Saya dapat mengaturnya menggunakan solusi @Hieu Rocker, namun ada beberapa kelemahan kecil yaitu dalam proyek kami kami menggunakan rasa dan memiliki beberapa tes tambahan untuk rasa tersebut serta kode java tambahan untuk masing-masing. Kami juga menggunakan jenis build yang berbeda. Oleh karena itu solusi untuk mengandalkan tugas "testDebug" tidak cukup baik. Inilah solusi saya: Di build.gradle di aplikasi modul ditambahkan

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

Kemudian buat a jacoco.gradle file dalam aplikasi modul dengan konten berikut:


    terapkan plugin: 'jacoco'

    jacoco {
        toolVersion "0.7.1.201405082137"
    }

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

    def getBuildTypeFromVariant (String variantName) {
        def buildTypeString = variantName.replaceAll (/ (. *) ([A-Z]. *) /) {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", ketik: JacocoReport, dependsOn: testTaskName) {
            grup = "Pelaporan"
            description = "Buat laporan cakupan JaCoCo setelah menjalankan tes untuk varian: $ {variantName}."
            laporan {
                xml.enabled = true
                html.enabled = true
            }

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

            logger.info ("Konfigurasi JaCoCo untuk rasa: $ {flavorFromVariant}, buildType: $ {buildTypeFromVariant}, tugas: $ {testTaskName}");

            def coverageSourceDirs = [
                    '../app/src/main/java',
                    "../app/src/${flavorFromVariant}/java"
            ]
            sourceDirectories = files (coverageSourceDirs)
            executionData = file ("$ buildDir / jacoco / $ {testTaskName} .exec")
            // Bit hacky tetapi perbaikan https://code.google.com/p/android/issues/detail?id=69174.
            // Kami melakukan iterasi melalui pohon .class terkompilasi dan mengganti nama $$ menjadi $.
            doFirst {
                File baru ("$ buildDir / intermediates / classes /"). eachFileRecurse {file ->
                    if (file.name.contains ('$$')) {
                        file.renameTo (file.path.replace ('$$', '$'))
                    }
                }
            }
        }
    }

Anda dapat menjalankannya dari baris perintah seperti ini:

.gradlew jacocoFlavor1DebugTestReport

atau

.gradlew jacocoOtherflavorPrereleaseTestReport

Dalam proyek kami, kami menggunakan konvensi untuk tidak menggunakan huruf besar di dalam rasa dan membangun nama jenis, tetapi jika proyek Anda tidak mengikuti konvensi ini, Anda dapat dengan mudah mengubah getFlavorFromVariant (..) dan getBuildTypeFromVariant (..) fungsi

Semoga ini bisa membantu seseorang


6
2018-06-16 10:05



Anda dapat mencoba menggunakan plugin Gradle ini: https://github.com/arturdm/jacoco-android-gradle-plugin

Ada sedikit lagi jawabannya di sini https://stackoverflow.com/a/32572259/1711454.


0
2017-09-14 19:22



Apakah Anda mencoba menambahkan yang berikut:

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

Dan kemudian bukannya berlari ./gradlew jacocoTestReport menjalankan ./gradlew test jacocoTestReport.

Jika semua berjalan dengan baik Anda harus menemukan hasil tes di build/reports/jacoco/test/html/index.html.


-3
2017-12-11 16:40