web-dev-qa-db-ja.com

Android StudioとフレーバーのJacocoコードカバレッジ

私はしばらくの間、Jacocoテストカバレッジを静かに実行しようとしています。私はこれらのトピックで報告されたいくつかの可能な解決策を試しました:

JaCoCo GradleプラグインによるAndroidテストコードカバレッジ

Android gradleプラグイン0.10.0以降を使用してjacocoカバレッジレポートを取得するにはどうすればよいですか?

Genymotionを使用してエミュレートされたデバイスでテストを実行しています。これが私がbuild.gradleに追加したものです:

apply plugin: 'jacoco'

Android{       
    jacoco {
        version "0.7.1.201405082137"
    }        
    buildTypes{
        debug{
                    testCoverageEnabled = true
        }
    }
}

jacoco {
    toolVersion "0.7.1.201405082137"
}

それを実行するには、私は次のようなものを使用します

./gradlew clean
./gradlew createFLAVOR_NAMEDebugCoverageReport

関連する生成されたファイル/フォルダーは次のとおりです。

/build/intermediates/coverage-instrumented-classes
/build/intermediates/jacoco
/build/outputs/code-coverage/connected/flavors/MyFlavor/coverage.ec

ただし、@ build/reports/jacoco/test/html /index.htmlやhtmlページ/コードカバレッジレポート@/build/outputsには何もありません。

また、カバレッジレポートを作成するための専用タスクを作成しようとしました。

def coverageSourceDirs = [
    'src/main/Java',
]

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

次に、./ gradlew cleanおよび./ gradlew jacocoTestReport。出力は上記と同じであるため、カバレッジレポートやその他のカバレッジファイルを含むhtmlページはありません。

私は現在Android Studiov1.0.2と最新のgradleバージョンを使用しています。gradleはかなり新しいので、ここで基本的なものが欠落している可能性があります。

ありがとう

17
Adr3nl

この問題を追いかけて一日を過ごした後、私は何が問題なのかを見つけました。例とは異なり、testDebugビルドによって生成されたファイルは.execファイルではありません@ $ buildDir/jacoco/testDebug.exec

私のgradleとstudioバージョンでは、生成されるファイルは.ec @ build/outputs/code-coverage/connected/flavors/myFlavor/Coverage.ec

これに関連する情報は見つかりませんでした。最近の変更かもしれませんが、カスタムJacocoReportタスクを作成し、それに応じてexecutionData変数を変更することで、問題を解決しました。これが私の実装です:

task jacocoTestReport(type: JacocoReport) {

  def coverageSourceDirs = [
        'src/main/Java'
  ]

  group = "Reporting"
  description = "Generates Jacoco coverage reports"
  reports {
      xml{
          enabled = true
          destination "${buildDir}/reports/jacoco/jacoco.xml"
      }
      csv.enabled false
      html{
          enabled true
          destination "${buildDir}/jacocoHtml"
      }
  }

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

  sourceDirectories = files(coverageSourceDirs)
  additionalSourceDirs = files(coverageSourceDirs)
  executionData = files('build/outputs/code-coverage/connected/flavors/smartcompanion/coverage.ec')
}
10
Adr3nl

AndroidフレーバーでJacocoを使用したカバレッジレポートをテストします:

「無料」と「有料」という名前のフレーバーがあるとしましょう

  • Step1:build.gradleが存在するプロジェクトモジュールディレクトリ(デフォルトではアプリ)にjacoco.gradleファイルを作成します。これはbuild.gradleファイルの隣にある必要があります。以下に示すディレクトリ構造

    アプリ> jacoco.gradle

  • ステップ2:ステップ1で作成したファイルにコードの下に貼り付けます。コードには理解できる自明のコメントがあります

apply plugin: 'jacoco'

jacoco {
    toolVersion = "0.7.5.201505241946"
}
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
    }
    // When no product flavors defined, use empty
    if (!productFlavors) productFlavors.add('')

    //iterate over the flavors

    productFlavors.each {

        productFlavorName ->
//iterate over build types like debug,release,prod etc.
        buildTypes.each {

            buildTypeName ->
                //sourceName — e.g. freeDebug ,sourcePath — e.g. free/debug
            def sourceName, sourcePath
            if (!productFlavorName) {
                sourceName = sourcePath = "${buildTypeName}"
            } else {
                sourceName = "${productFlavorName}${buildTypeName.capitalize()}"
                sourcePath = "${productFlavorName}/${buildTypeName}"
            }
                // testTaskName —  e.g. testFreeDebugtest task that the coverage task depends on,
            def testTaskName = "test${sourceName.capitalize()}UnitTest"
            // 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")
                reports {
                    //enables and disable the type of file you need
                    xml.enabled = false
                    html.enabled = true
                }
            }
        }
    }
}
  • ステップ3:Android studio terminalで以下のコマンドを実行して、アプリケーションをビルドします

    ./gradlewクリーンアセンブル

  • ステップ4:ビルドが成功したら、以下のコマンドを実行してテストレポートを生成します(文字列「testFreeDebugUnitTestCoverage」を特定のフレーバー/ビルドタイプに変更します。たとえば、有料バージョンの場合、コマンドは./gradlew testPaidDebugUnitTestCoverageになります)

    ./gradlew testFreeDebugUnitTestCoverage

  • ステップ5:

ターミナルに成功メッセージが表示されるはずです。ディレクトリに移動します。

>app > build > reports >jacoco >${testName} >look for html or xml file report file
  • ステップ6:これで、ブラウザでhtmlテストカバレッジファイルを開いて表示できます。

幸運を祈ります!!!

1
Pravin Madavi