34

Gradle と Android のテストは初めてですが、既に Android プロジェクトを Gradle でビルドするように変換しています。

現在、Gradle の JaCoCo プラグインを使用して Android プロジェクトのテスト カバレッジを実行しようとしています。

build.gradle ファイルに以下を追加しました。

apply plugin: 'jacoco'

「gradle jacocoTestReport」を実行すると、次のエラーが表示されます。

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

ドキュメントから、プラグイン「java」も適用することになっていますが、プラグイン「android」と競合します。

これを回避する方法はありますか?

前もって感謝します。

4

4 に答える 4

23

これが私が使用している方法です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'
  }
}

上記のコードには、https://code.google.com/p/android/issues/detail?id=69174の回避策も含まれています。

詳細: http://chrisjenx.com/gradle-robolectric-jacoco-dagger/

于 2014-06-15T15:36:04.137 に答える
7

RoboGuice、Butterknife、および Robolectric を使用するプロジェクトで JaCoCo を使用しています。@Hieu Rocker のソリューションを使用してセットアップできましたが、いくつかの小さな欠点がありました。つまり、私たちのプロジェクトではフレーバーを使用しており、それらのフレーバーに対していくつかの追加のテストと、それぞれの追加の Java コードがあります。また、さまざまなビルドタイプを使用しています。したがって、「testDebug」タスクに依存するソリューションは十分ではありませんでした。これが私の解決策です:アプリモジュールのbuild.gradleに追加します

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

次に、アプリモジュール内に次の内容のjacoco.gradleファイルを作成します。

    プラグインを適用: 'jacoco'

    ジャココ {
        ツールバージョン「0.7.1.201405082137」
    }

    def getFlavorFromVariant(String variantName) {
        defflavorString = variantName.replaceAll(/(.*)([AZ].*)/) {すべて、flavorName、buildTypeName ->
           フレーバー名
        }
        フレーバー文字列を返します。
    }

    def getBuildTypeFromVariant(String variantName) {
        def buildTypeString = variantName.replaceAll(/(.*)([AZ].*)/) { すべて、フレーバー名、ビルドタイプ名 ->
            「${buildTypeName.toLowerCase()}」
        }
        buildTypeString を返します。
    }

    def getFullTestTaskName(String variantName) {
        return "test${variantName.capitalize()}UnitTest";
    }

    android.applicationVariants.all { バリアント ->
        def variantName = variant.name;
        deflavorFromVariant = getFlavorFromVariant("${variantName}");
        def buildTypeFromVariant = getBuildTypeFromVariant("${variantName}");
        def testTaskName = getFullTestTaskName("${variantName}")

        task ("jacoco${variantName.capitalize()}TestReport"、タイプ: JacocoReport、dependsOn: testTaskName) {
            グループ = "レポート"
            description = "バリアントのテストを実行した後、JaCoCo カバレッジ レポートを生成します: ${variantName}。"
            レポート {
                xml.enabled = true
                html.enabled = true
            }

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

            logger.info("フレーバー用に JaCoCo を構成しています: ${flavorFromVariant}、buildType: ${buildTypeFromVariant}、タスク: ${testTaskName}");

            デフカバレッジSourceDirs = [
                    '../app/src/main/java',
                    "../app/src/${flavorFromVariant}/java"
            ]
            sourceDirectories = files(coverageSourceDirs)
            executionData = files("$buildDir/jacoco/${testTaskName}.exec")
            // ちょっとハックですが、https://code.google.com/p/android/issues/detail?id=69174 を修正します。
            // コンパイルされた .class ツリーを繰り返し処理し、$$ を $ に名前変更します。
            doFirst {
                new File("$buildDir/intermediates/classes/").eachFileRecurse { ファイル ->
                    if (file.name.contains('$$')) {
                        file.renameTo(file.path.replace('$$', '$'))
                    }
                }
            }
        }
    }

次のようにコマンドラインから実行できます。

.gradlew jacocoFlavor1DebugTestReport

また

.gradlew jacocoOtherflavorPrereleaseTestReport

私たちのプロジェクトでは、フレーバー名とビルド タイプ名に大文字を使用しないという規則を使用していますが、プロジェクトがこの規則に従っていない場合は、getFlavorFromVariant(..)およびgetBuildTypeFromVariant(..)関数を変更するだけです。

これが誰かを助けることを願っています

于 2015-06-16T10:05:06.617 に答える
0

この Gradle プラグインを使用してみることができます: https://github.com/arturdm/jacoco-android-gradle-plugin

https://stackoverflow.com/a/32572259/1711454の回答にはもう少しあります。

于 2015-09-14T19:22:14.233 に答える
-4

以下を追加してみましたか?

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

そして、./gradlew jacocoTestReportrunを実行する代わりに./gradlew test jacocoTestReport

すべてがうまくいけば、でテスト結果が見つかるはずbuild/reports/jacoco/test/html/index.htmlです。

于 2013-12-11T16:40:02.093 に答える