web-dev-qa-db-ja.com

Android-gradle-plugin> = 1.1を使用したJacocoと単体テストのコードカバレッジ

最近、私のプロジェクトの1つにAndroid-gradle-plugin 1.1.0の統合を開始しました。プロジェクトは、robolectric 2.4を使用して単体テストを実行します。

非常に複雑な依存関係を持つマルチモジュールプロジェクトです(一部のモジュールは他のモジュールに依存しています)。そんな感じ:

--> application-module (dependsOn: module1, module2, module-core)
    --> module1 (dependsOn: module-core)
    --> module2 (dependsOn: module-core)
    --> module-core (dependsOn: module3, module4)
        --> module3 (library dependencies)
        --> module4 (library dependencies)

よりクリアな画像については、 jacoco-example プロジェクトを参照してください。

JaCoCoを統合して単体テスト用のレポートを生成しようとしましたが、基本的には計測テストであるandroidTestsのみを実行しているようです。

グーグルで調べた後、GitHubやその他の記事でいくつかのプロジェクトに出会いましたが、主に以前のバージョンのAndroid-gradle-pluginに焦点を当てているか、Android-unit-testなどの他のサードパーティプラグインを使用しています たとえばここ

グーグルの能力を失ったのかもしれません。しかし、誰かが私にAndroid gradleプラグインと単体テストのためにjacocoタスクを実行する方法の新しいものに関するドキュメントを見つけることができる方向に私を向けることができますか?

[〜#〜] update [〜#〜]

nenickの例 からのスクリプトを採用しました:

apply plugin: "jacoco"

configurations {
    jacocoReport
}

task jacocoReport(dependsOn: 'testDebug') << {
    ant {
        taskdef(name:'jacocoreport',
                classname: 'org.jacoco.ant.ReportTask',
                classpath: configurations.jacocoReport.asPath)

        mkdir dir: "${buildDir}/test-coverage-report"
        mkdir dir: "${buildDir}/reports/jacoco/test/"

        jacocoreport {
            executiondata = files("${buildDir}/jacoco/testDebug.exec")

            structure(name: "${rootProject.name}") {
                classfiles {
                    fileset (dir: "${buildDir}/intermediates/classes/debug") {
                        //exclude(name: '**/*_*.class')
                        exclude(name: '**/R.class')
                        exclude(name: '**/R$*.class')
                        exclude(name: '**/BuildConfig.class')
                    }
                }

                sourcefiles {
                    fileset dir: "src/main/Java"
                    fileset dir: "${buildDir}/generated/source/buildConfig/debug"
                    fileset dir: "${buildDir}/generated/source/r/debug"
                }
            }

            xml destfile: "${buildDir}/reports/jacoco/test/jacocoTestReport.xml"
            html destdir: "${buildDir}/test-coverage-report/"
        }
    }
}

dependencies {
    jacocoReport 'org.jacoco:org.jacoco.ant:0.7.2.201409121644'
}

その後、./gradlew jacocoReportが実行されてレポートが生成されますが、テストカバレッジは0(ゼロ)を示します。これは、すべてのクラスの少なくとも半分がテストされるため不可能です。

UPDATE_2

これを試してみました 。私のgradleビルドファイルの1つに次のタスクを追加します:

task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug") {
    group = "Reporting"
    description = "Generate Jacoco coverage reports"

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

    sourceDirectories = files("${buildDir.parent}/src/main/Java")
    additionalSourceDirs = files([
            "${buildDir}/generated/source/buildConfig/debug",
            "${buildDir}/generated/source/r/debug"
    ])
    executionData = files("${buildDir}/jacoco/testDebug.exec")

    reports {
        xml.enabled = true
        html.enabled = true
    }
}

同じ問題、レポートは生成されますが、コードカバレッジはまだゼロです。

UPDATE_3

UPDATE_2からのタスクはapply plugin: 'com.Android.application'(レポートが正しく生成された)のモジュールに対してのみ機能したと継ぎ目があります。しかし、モジュールがAndroidライブラリ(apply plugin: 'com.Android.library')の場合、レポートにはカバレッジがゼロと表示されますが、モジュールにはアプリケーションモジュールよりも多くのテストが含まれます。

UPDATE_4

私の問題を示す簡単なサンプルプロジェクトを作成しました。現在、./gradlew jacocoReportを実行すると、レポートが生成されますが、モジュールプロジェクトのテストカバレッジは表示されません。こちらをご覧ください link

ショートノート:テストがAndroidUnitTests(ホワイトアウトJUnit 4およびRobolectric)の場合、JaCoCoレポートはすべてのモジュールのカバレッジを示しました。

何か案は?

35
Serj Lotutovici

面倒の後、私は オープンソースのGradleプラグイン を作成することにしました。

ルートbuild.gradle

buildscript {
    repositories {
        mavenCentral() // optional if you have this one already
    }
    dependencies {
        classpath 'com.vanniktech:gradle-Android-junit-jacoco-plugin:0.8.0'
    }
}

apply plugin: 'com.vanniktech.Android.junit.jacoco'

その後、単に実行する

./gradlew jacocoTestReportDebug

デバッグモードでJUnitテストを実行し、対応するビルドディレクトリでxmlおよびhtml形式のJacoco出力を提供します。

フレーバーもサポートしています。これらのタスクが作成される赤と青の2つのフレーバーを持つ

  • jacocoTestReportRedDebug
  • jacocoTestReportBlueDebug
  • jacocoTestReportRedRelease
  • jacocoTestReportBlueRelease
14
Niklas

いくつかの追加検索の後、私はこれにつまずいた project 私のタイプのプロジェクトでソリューションが機能するようにいくつかの変更を行う必要がありましたが、今ではテストカバレッジレポートが適切に生成されます。

将来同様の問題が発生する場合に備えて、採用した変更を github repoの例 にプッシュしました。

8
Serj Lotutovici

これを使用してgradle 1.2の単体テストをセットアップします ブログ投稿 。その後、ここで見つけた情報をつなぎ合わせて、プロジェクト全体ではなく独立したモジュールにコードカバレッジを追加しました。ライブラリモジュールでbuild.gradleファイル、次を追加しました。

apply plugin: 'jacoco'

def jacocoExcludes = [
        'com/mylibrary/excludedpackage/**'
]

Android {
    ...
}

Android.libraryVariants.all { variant ->
    task("test${variant.name.capitalize()}WithCoverage", type: JacocoReport, dependsOn: "test${variant.name.capitalize()}") {
        group = 'verification'
        description = "Run unit test for the ${variant.name} build with Jacoco code coverage reports."

        classDirectories = fileTree(
                dir: variant.javaCompile.destinationDir,
                excludes: rootProject.ext.jacocoExcludes.plus(jacocoExcludes)
        )
        sourceDirectories = files(variant.javaCompile.source)
        executionData = files("${buildDir}/jacoco/test${variant.name.capitalize()}.exec")

        reports {
            xml.enabled true
            xml.destination "${buildDir}/reports/jacoco/${variant.name}/${variant.name}.xml"
            html.destination "${buildDir}/reports/jacoco/${variant.name}/html"
        }
    }
}

そして私のプロジェクトではbuild.gradleファイル、一般的な除外を追加しました:

ext.jacocoExcludes = [
    'Android/**',
    '**/*$$*',
    '**/R.class',
    '**/R$*.class',
    '**/BuildConfig.*',
    '**/Manifest*.*',
    '**/*Service.*'
]

また、単体テストのコードカバレッジは今後組み込まれる可能性があるようです Issue 144664

3
Chris Feist

Android Studio 1.1。でJUnitテストのコードカバレッジを確認できました。

jacoco.gradle

apply plugin: 'jacoco'

jacoco {
    toolVersion "0.7.1.201405082137"
}

def coverageSourceDirs = [
        "$projectDir/src/main/Java",
]

task jacocoTestReport(type: JacocoReport, dependsOn: "testDebug") {
    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('$$', '$'))
            }
        }
    }
}

次に、モジュールのbuild.gradleファイル内で(Androiddependenciesの間に配置します):

apply from: '../jacoco.gradle'

defaultConfigAndroidブロックにも。これを追加しました(必要かどうかはわかりませんが、これは このブログ から取得しています):

Android {
    defaultConfig {
        testHandleProfiling true
        testFunctionalTest true
    }
}

楽しい。

2
Niklas

警告:これはハックです!上記の設定を使用して、選択したビルドタスクに応じて、アプリケーションとライブラリ間でAndroidプラグインを切り替えるためのハックを作成しました。設定されたアプリケーションモード。

// dynamically change the Android plugin to application if we are running unit tests or test reports.
project.ext.androidPlugin = 'com.Android.library'
for (String taskName : project.gradle.startParameter.taskNames) {
    if (taskName.contains('UnitTest') || taskName.contains('jacocoTestReport')) {
        project.ext.androidPlugin = 'com.Android.application'
        break
    }
}

logger.lifecycle("Setting Android pluging to ${project.ext.androidPlugin}")
apply plugin: project.ext.androidPlugin

...

apply plugin: 'jacoco'

configurations {
    jacocoReport
}

task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug") {
    group = "Reporting"
    description = "Generate Jacoco coverage reports"

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

    sourceDirectories = files("${buildDir.parent}/src/main/Java")
    additionalSourceDirs = files([
            "${buildDir}/generated/source/buildConfig/debug",
            "${buildDir}/generated/source/r/debug"
    ])
    executionData = files("${buildDir}/jacoco/testDebug.exec")

    reports {
        xml.enabled = true
        html.enabled = true
    }
}

Androidツールチームがこれをすぐに修正することを期待しましょう。

2
vangorra

このGradleプラグインを使用してみてください: https://github.com/arturdm/jacoco-Android-gradle-plugin

基本的に、あなたがする必要があるのはこのようにそれを適用することです:

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'com.dicedmelon.gradle:jacoco-Android:0.1.1'
  }
}

apply plugin: 'com.Android.library' // or 'com.Android.application'
apply plugin: 'jacoco-Android'

その結果、各バリアントに対してJacocoReportタスクを取得する必要があります。以下のコマンドを実行して、すべてのコードカバレッジレポートを生成します。

$ ./gradlew jacocoTestReport
1

私はあなたとまったく同じ問題に直面していました。今日、完全に削除しましたAndroid studio、Android sdk、gradle。その後、すべてを再インストールします。その後、アプリbuild.gradle内に追加しました。

debug {testCoverageEnabled true}その後、。/ gradlew connectedChecを実行します。すべてが完璧に機能しています。 AndroidスタジオデフォルトのJacocoは私のためにうまく機能しています。jacocoTestReportタスクを作成してからコードカバレッジを作成することも可能だと思います。なぜgradleとAndroidスタジオは以前は機能していませんでした。

1
user1365169

JaCoCoの問題を解決し、最新のgradleで動作させるAndroid plugin 1.1.3

最新のgradleスクリプトを使用したプロジェクト: https://github.com/OleksandrKucherenko/meter

参照:

Android Studio Unit Tests?https:// plusでモックの代わりに独自の実装をアタッチする方法.google.com/117981280628062796190/posts/8jWV22mnqUB

Android builds ...予期しない発見!!!)でJaCoCoカバレッジを使用しようとするすべての人のための小さなヒント https://plus.google.com/117981280628062796190/posts/RreU44qmeuP

ユニットテストのJaCoCo XML/HTMLレポートhttps://plus.google.com/u/0/+OleksandrKucherenko/posts/6vNWkkLed3b

例を作成してください、私は見てみることができます。パス構成が欠落していると思います。

  • すべてのカバレッジファイル(* .exec)を含める
  • すべてのソースパス(module/src/main/Java)を追加します
  • すべてのクラスパスを追加します(モジュール/ビルド/中間体/クラス/デバッグ)

ここに2つの例があります

0
nenick