web-dev-qa-db-ja.com

JaCoCoはロボレクトリックテストでは機能しません

AndroidプロジェクトでJUnitテストのコードカバレッジレポートを生成したかったので、JaCoCogradleプラグインを追加しました。これはプロジェクトレベルのbuild.gradleファイルです。

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() })
    }
}

./gradlew jacocoFullReportを実行するとうまく機能します。ただし、残念ながら、RobolectricTestRunnerで実行されたテストのカバレッジは報告されていません(テストで明らかに呼び出された命令は、カバーされたものとして報告されません)。 @RunWithアノテーションなしでテストするか、MockitoJUnitTestRunnerレポートカバレッジで実行すると問題ありません。

この問題を解決するために助けをいただければ幸いです。

更新1:RobolectricGradleTestRunnerを使用する必要があることに気づきました。しかし、それは役に立ちませんでした。

21
Longi

考えられる回避策の既知の問題-- https://github.com/jacoco/jacoco/pull/288

または、jacocoバージョンを0.7.1.201405082137にダウングレードします

[〜#〜]更新[〜#〜]

回避策はもう必要ありません。 gradleバージョン2.13およびjacocoバージョン0.7.6.201602180812を使用する必要があります。

ルートbuild.gradleを更新します。

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

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

./gradlew wrapperを実行します

プロジェクトの更新build.gradle

apply plugin: 'jacoco'

Android {
  testOptions {
    unitTests.all {
      jacoco {
        includeNoLocationClasses = true
      }
    }
  }
}
17
Eugen Martynov

受け入れられた答えは少し時代遅れです。これは、先ほど実装した同様の修正です。モジュール(つまりアプリ)にbuild.gradleを追加します:

apply plugin: 'jacoco'

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

これにはJaCoCo7.6以降が必要ですが、すでに使用している可能性があります。

スタジオに関する注意事項:

  1. これはCLIを修正するだけです。 JaCoCoを使用してStudioからカバレッジを実行した場合でも、Robolectricカバレッジは報告されません。デフォルトのIntelliJカバレッジランナーは正常に動作しているようです。
  2. Android JUnit-> VM Optionsに-noverifyを追加しない限り、Studioでテストが断続的にクラッシュしていました
4
Dustin

私は同じ問題に直面していましたが、このリンクをたどることで解決されました。

問題のリンク: https://github.com/robolectric/robolectric/issues/22

この問題の解決策はここに記載されています:

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

3
shahzad

私も同じ問題を抱えていました。 jacocoプラグインのバージョンを変更し、includenolocationclassesプロパティを追加しました。動作するjacoco.gradleファイルは次のとおりです(私はgradleラッパー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
                }
            }
        }
    }
}
2
Ashwani Kumar

Android studio 1-アプリ(プロジェクトのルート)を選択)でカバレッジランナーをjacocoに変更します2メニューをクリックします(実行->構成の編集->コードカバレッジ-> JaCoCoを選択します)。

the screenshot is below

0
Houssin Boulla