Frage JaCoCo funktioniert nicht mit Robolectric-Tests


Ich wollte Code-Coverage-Berichte für meine JUnit-Tests in meinem Android-Projekt erstellen, also habe ich das JaCoCo-Gradle-Plugin hinzugefügt. Das ist meine Projektebene build.gradle Datei:

apply plugin: 'jacoco'

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.0.0-beta6'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

allprojects {
    repositories {
        jcenter()
        maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

subprojects { prj ->
    apply plugin: 'jacoco'

    jacoco {
        toolVersion '0.7.6.201602180812'
    }

    task jacocoReport(type: JacocoReport, dependsOn: 'testDebugUnitTest') {
        group = 'Reporting'
        description = 'Generate Jacoco coverage reports after running tests.'

        reports {
            xml {
                enabled = true
                destination "${prj.buildDir}/reports/jacoco/jacoco.xml"
            }
            html {
                enabled = true
                destination "${prj.buildDir}/reports/jacoco"
            }
        }

        classDirectories = fileTree(
                dir: 'build/intermediates/classes/debug',
                excludes: [
                        '**/R*.class',
                        '**/BuildConfig*',
                        '**/*$$*'
                ]
        )

        sourceDirectories = files('src/main/java')
        executionData = files('build/jacoco/testDebugUnitTest.exec')

        doFirst {
            files('build/intermediates/classes/debug').getFiles().each { file ->
                if (file.name.contains('$$')) {
                    file.renameTo(file.path.replace('$$', '$'))
                }
            }
        }
    }
}

jacoco {
    toolVersion '0.7.6.201602180812'
}

task jacocoFullReport(type: JacocoReport, group: 'Coverage reports') {
    group = 'Reporting'
    description = 'Generates an aggregate report from all subprojects'

    //noinspection GrUnresolvedAccess
    dependsOn(subprojects.jacocoReport)

    additionalSourceDirs = project.files(subprojects.jacocoReport.sourceDirectories)
    sourceDirectories = project.files(subprojects.jacocoReport.sourceDirectories)
    classDirectories = project.files(subprojects.jacocoReport.classDirectories)
    executionData = project.files(subprojects.jacocoReport.executionData)

    reports {
        xml {
            enabled = true
            destination "${buildDir}/reports/jacoco/full/jacoco.xml"
        }
        html {
            enabled = true
            destination "${buildDir}/reports/jacoco/full"
        }
    }

    doFirst {
        //noinspection GroovyAssignabilityCheck
        executionData = files(executionData.findAll { it.exists() })
    }
}

Es funktioniert großartig beim Laufen ./gradlew jacocoFullReport. Aber leider wird Berichterstattung nicht für die Tests berichtet, die mit dem laufen gelassen werden RobolectricTestRunner (Anweisungen, die offensichtlich in den Tests aufgerufen werden, werden nicht als abgedeckt gemeldet). Tests mit Nein @RunWith Anmerkung oder laufe mit MockitoJUnitTestRunner berichten Berichterstattung gut.

Jede Hilfe wäre willkommen, um dieses Problem zu beheben.

Update 1: Ich habe bemerkt, dass ich das benutzen sollte RobolectricGradleTestRunner. Aber es hat nicht geholfen.


16
2018-03-01 22:42


Ursprung


Antworten:


Es ist bekannt, Problem mit der möglichen Problemumgehung - https://github.com/jacoco/jacoco/pull/288

Oder Downgrade Jacoco Version zu 0.7.1.201405082137

AKTUALISIEREN

Die Problemumgehung wird nicht mehr benötigt. Sie müssen verwenden Gradel Ausführung 2.13 und Jacoco Ausführung 0.7.6.201602180812.

Wurzel aktualisieren build.gradle:

buildscript {
    dependencies {
        classpath 'org.jacoco:org.jacoco.core:0.7.6.201602180812'
    }
}

task wrapper( type: Wrapper ) {
  gradleVersion = '2.13'
}

Lauf ./gradlew wrapper

Projekt aktualisieren build.gradle:

apply plugin: 'jacoco'

android {
  testOptions {
    unitTests.all {
      jacoco {
        includeNoLocationClasses = true
      }
    }
  }
}

14
2018-03-02 14:49



Ich stand vor demselben Problem, aber jetzt ist es für mich gelöst, indem ich diesem Link folge,

Link ausgeben: https://github.com/robolectric/robolectric/issues/2230

Lösung für dieses Problem wird hier erwähnt:

https://github.com/dampcake/Robolectric-JaCoCo-Sample/commit/f9884b96ba5e456cddb3d4d2df277065bb26f1d3


3
2018-03-03 10:44



Ich hatte das gleiche Problem. Ich habe die jacoco-Plugin-Version geändert und die Eigenschaft includeolocationclasses hinzugefügt. Hier ist die Arbeit jacoco.gradle Datei (Ich benutze Gradle Wrapper 2.14.1):

apply plugin: 'jacoco'

jacoco {
    toolVersion = "0.7.6.201602180812"
}

android {
    testOptions {
        unitTests.all {
            jacoco {
                includeNoLocationClasses = true
            }
        }
    }
}

project.afterEvaluate {
    // Grab all build types and product flavors
    def buildTypes = android.buildTypes.collect { type -> type.name }
    def productFlavors = android.productFlavors.collect { flavor -> flavor.name }
    println(buildTypes)
    println(productFlavors)
    // When no product flavors defined, use empty
    if (!productFlavors) productFlavors.add('')

    productFlavors.each { productFlavorName ->
        buildTypes.each { buildTypeName ->
            def sourceName, sourcePath
            if (!productFlavorName) {
                sourceName = sourcePath = "${buildTypeName}"
            } else {
                sourceName = "${productFlavorName}${buildTypeName.capitalize()}"
                sourcePath = "${productFlavorName}/${buildTypeName}"
            }
            def testTaskName = "test${sourceName.capitalize()}UnitTest"
            println("SourceName:${sourceName}")
            println("SourcePath:${sourcePath}")
            println("testTaskName:${testTaskName}")
            // Create coverage task of form 'testFlavorTypeCoverage' depending on 'testFlavorTypeUnitTest'
            task "${testTaskName}Coverage" (type:JacocoReport, dependsOn: "$testTaskName") {
                group = "Reporting"
                description = "Generate Jacoco coverage reports on the ${sourceName.capitalize()} build."

                classDirectories = fileTree(
                        dir: "${project.buildDir}/intermediates/classes/${sourcePath}",
                        excludes: ['**/R.class',
                                   '**/R$*.class',
                                   '**/*$ViewInjector*.*',
                                   '**/*$ViewBinder*.*',
                                   '**/BuildConfig.*',
                                   '**/Manifest*.*']
                )

                def coverageSourceDirs = [
                        "src/main/java",
                        "src/$productFlavorName/java",
                        "src/$buildTypeName/java"
                ]
                additionalSourceDirs = files(coverageSourceDirs)
                sourceDirectories = files(coverageSourceDirs)
                executionData = files("${project.buildDir}/jacoco/${testTaskName}.exec")
                println("${project.buildDir}/jacoco/${testTaskName}.exec")
                reports {
                    xml.enabled = true
                    html.enabled = true
                }
            }
        }
    }
}

1
2018-05-12 06:13



Die angenommene Antwort ist etwas veraltet. Hier ist ein ähnlicher Fix, den wir gerade implementiert haben. Im Modul (d. H. App) build.gradle add:

apply plugin: 'jacoco'

tasks.withType(Test) {
    jacoco.includeNoLocationClasses = true
}

Dies erfordert JaCoCo 7.6+, aber Sie verwenden es wahrscheinlich bereits.

Hinweise für Studio:

  1. Dies behebt nur die CLI. Wenn Sie Coverage von Studio aus mit JaCoCo ausführen, wird die Robolectric-Abdeckung weiterhin nicht gemeldet. Der standardmäßige IntelliJ Coverage Runner scheint einwandfrei zu funktionieren.
  2. Der Test stürzte zeitweise in Studio ab, es sei denn, ich habe -noverify zu Android JUnit -> VM Options hinzugefügt

0
2018-06-21 21:59