web-dev-qa-db-ja.com

マルチモジュールのグローバルコードカバレッジAndroidプロジェクト:マージコードカバレッジレポート(ユニットおよびUIテスト)

2つのモジュールで構成されるAndroidアプリがあります:

  • アプリ-UI

  • サブモジュール-ほとんどのビジネスロジックがあります

それらのそれぞれについて、コードカバレッジを検証するためのgradleタスクがあります。

  • アプリ:UIコードカバレッジ(エスプレッソ)

  • サブモジュール:ユニットテストのコードカバレッジ

クライアントの要件として、全体的/グローバルなコードカバレッジを取得するには、これら2つのレポートをマージする必要がありますアプリの。

注:私はGradleバージョン3.1.2。を使用しています


アプリGradleファイル:

apply plugin: 'jacoco'

Android {

   testBuildType "uiTest"

    ...

  buildTypes {
    debug {
        applicationIdSuffix ".debug"
        versionNameSuffix "-debug"
        debuggable true

        minifyEnabled false
        shrinkResources false
        proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'


        matchingFallbacks = ['debug']
    }

    // TESTS

    // unitTest will be used to run unit tests.
    unitTest.initWith(buildTypes.debug) //Beware the buildType this depends on MUST be above on the gradle file
    unitTest {
        applicationIdSuffix ".unitTest"
        versionNameSuffix "-unitTest"

        testCoverageEnabled = true
        matchingFallbacks = ['unitTest', 'debug']
    }

    // uiTest will be used to run ui tests.
    uiTest.initWith(buildTypes.debug) //Beware the buildType this depends on MUST be above on the gradle file
    uiTest {
        applicationIdSuffix ".uiTest"
        versionNameSuffix "-uiTest"

        testCoverageEnabled = true
        matchingFallbacks = ['uiTest', 'debug']
    }

    ...

サブモジュールGradleファイル:

apply plugin: 'jacoco'

Android {

   testBuildType "uiTest"

   buildTypes {
    debug {
    }

    unitTest {
        initWith(buildTypes.debug)
        testCoverageEnabled = true
    }

    uiTest {
        initWith(buildTypes.debug)
        testCoverageEnabled = true
    }

  ...
}

私はいくつかの方法を試しましたが、以下の方法は実際にテストをマージします。しかし、カバレッジが正しく表示されていません。

アプリでUIテストカバレッジを作成するタスク:

// UIテストカバレッジがフィルタリングされました(Jacocoを使用してフィルタリングできるようにするには、アプリの単体テストを実行する必要があります)

task createTestReport(type: JacocoReport, dependsOn: [':app:testUnitTestUnitTest', ':app:createUiTestAndroidTestCoverageReport']) {

reports {
    html.enabled = true
}

def fileFilter = [
        //Android stuff
        '**/R.class',
        '**/BR.class',
        '**/R$*.class',
        '**/BR$*.class',
        '**/BuildConfig.*',
        'Android/**/*.*',
        //Data Binding
        '**/*databinding',
        '**/*binders',
        '**/*layouts',
        '**/Manifest*.*',
        '**/*Test*.*',
        "**/services/**/model/**",
        //Utils
        '**/utils/*.*',
        '**/utils/**/*.*'
]

//To support Java coverage on Unit tests
def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/unitTest", excludes: fileFilter)
//To support Kotlin coverage on Unit tests
def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/unitTest", excludes: fileFilter)

def mainSrc = "${project.projectDir}/src/main/Java"
def debugSrc = "${project.projectDir}/src/debug/Java"

sourceDirectories = files([mainSrc, debugSrc])


def appAndroidTests = fileTree(dir: "${buildDir}/outputs/code-coverage/connected/", includes: ["**/*.ec"])
def appOtherAndroidTests = fileTree(dir: "${buildDir}/outputs/androidTest-results/connected/", includes: ["**/*.ec"])

classDirectories = files([debugTree], [kotlinDebugTree])
executionData = files("${buildDir}/jacoco/testUnitTestUnitTest.exec", appAndroidTests, appOtherAndroidTests)

}

サブモジュールでユニットテストカバレッジを作成するタスク:

//ユニットテストカバレッジがフィルタリングされました

task createTestReport(type:JacocoReport、dependsOn:['testUnitTestUnitTest']){

reports {
    html.enabled = true
}

def fileFilter = ['**/R.class',
                  '**/BR.class',
                  '**/R$*.class',
                  '**/BR$*.class',
                  '**/BuildConfig.*',
                  '**/*databinding/**/*.*',
                  '**/Manifest*.*',
                  '**/*Test*.*',
                  "**/services/**/model/**",
                  'Android/**/*.*',
                  '**/utils/*.*',
                  '**/utils/**/*.*']

//To support Java coverage on Unit tests
def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/unitTest", excludes: fileFilter)
//To support Kotlin coverage on Unit tests
def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/unitTest", excludes: fileFilter)

def mainSrc = "${project.projectDir}/src/main/Java"
def debugSrc = "${project.projectDir}/src/debug/Java"

sourceDirectories = files([mainSrc, debugSrc])


classDirectories = files([debugTree], [kotlinDebugTree])
executionData = files("${buildDir}/jacoco/testUnitTestUnitTest.exec")

}

アプリでグローバルカバレッジを作成するタスク:

//グローバルテストカバレッジ

task createGlobalTestReport(type:JacocoReport、dependsOn:[':app:testUnitTestUnitTest'、 ':app:createTestReport'、 ':submodule:testUnitTestUnitTest']){

reports {
    html.enabled = true
}

def fileFilter = [
        //Android stuff
        '**/R.class',
        '**/BR.class',
        '**/R$*.class',
        '**/BR$*.class',
        '**/BuildConfig.*',
        'Android/**/*.*',
        //Data Binding
        '**/*databinding',
        '**/*binders',
        '**/*layouts',
        '**/Manifest*.*',
        '**/*Test*.*',
        "**/services/**/model/**",
        //Utils
        '**/utils/*.*',
        '**/utils/**/*.*'
]

// Note: **/reviews/ReviewService*.* was added as BazaarVoice cannot be mocked

//To support Java coverage on Unit tests
def debugAppTree = fileTree(dir: "${buildDir}/intermediates/classes/unitTest", excludes: fileFilter)
//To support Kotlin coverage on Unit tests
def debugKotlinAppTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/unitTest", excludes: fileFilter)

def debugSdkTree = fileTree(dir: "..//build/intermediates/classes/unitTest", excludes: fileFilter)
def debugKotlinSdkTree = fileTree(dir: "../submodule/build/tmp/kotlin-classes/unitTest", excludes: fileFilter)


def mainAppSrc = "${project.projectDir}/src/main/Java"
def debugAppSrc = "${project.projectDir}/src/debug/Java"

def mainSdkSrc = "../submodule/src/main/Java"
def debugSdkSrc = "../submodule/src/debug/Java"


sourceDirectories = files([mainAppSrc, debugAppSrc,
                           mainSdkSrc, debugSdkSrc])


def appAndroidTests = fileTree(dir: "${buildDir}/outputs/code-coverage/connected/", includes: ["**/*.ec"])
def sdkAndroidTests = fileTree(dir: "../submodule/build/outputs/code-coverage/connected/", includes: ["**/*.ec"])

classDirectories = files([debugAppTree, debugSdkTree,
                          debugKotlinAppTree, debugKotlinSdkTree])
executionData = files("${buildDir}/jacoco/testUnitTestUnitTest.exec"
        , "../submodule/build/jacoco/testUnitTestUnitTest.exec"
        , appAndroidTests
        , sdkAndroidTests
)

}

どんな助けでも大歓迎です

16
Renato Almeida

複数のビルドタイプで機能するかどうかはわかりません。

それを単一のビルドタイプにマージしてみてください。

アプリGradleファイル:

apply plugin: 'jacoco'
Android {
   testBuildType "automationTest"
    ...
  buildTypes {
    debug {
        applicationIdSuffix ".debug"
        versionNameSuffix "-debug"
        debuggable true
        minifyEnabled false
        shrinkResources false
        proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'

        matchingFallbacks = ['debug']
    }
    // TESTS
    automationTest {
        applicationIdSuffix ".automationTest"
        versionNameSuffix "-automationTest"

        testCoverageEnabled = true
        matchingFallbacks = ['automationTest', 'debug']
    }
    ...

サブモジュールGradleファイル:

apply plugin: 'jacoco'
Android {

   buildTypes {
    debug {
    }

    automationTest {
        initWith(buildTypes.debug)
        testCoverageEnabled = true
    }

    release {
        initWith(buildTypes.debug)
    }
  ...
}

サブモジュールでユニットテストカバレッジを作成するタスク:

task createUnitTestReport(type: JacocoReport, dependsOn: ['testAutomationTestUnitTest']) {

reports {
    html.enabled = true
}

def fileFilter = ['**/R.class',
                  '**/BR.class',
                  '**/R$*.class',
                  '**/BR$*.class',
                  '**/BuildConfig.*',
                  '**/*databinding/**/*.*',
                  '**/Manifest*.*',
                  '**/*Test*.*',
                  'Android/**/*.*']

//To support Java coverage on Unit tests
def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/automationTest", excludes: fileFilter)
//To support Kotlin coverage on Unit tests
def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/automationTest", excludes: fileFilter)

def mainSrc = "${project.projectDir}/src/main/Java"
def debugSrc = "${project.projectDir}/src/debug/Java"

sourceDirectories = files([mainSrc, debugSrc])


classDirectories = files([debugTree], [kotlinDebugTree])
executionData = files("${buildDir}/jacoco/testAutomationTestUnitTest.exec")
}

アプリでグローバルカバレッジを作成するタスク:

task createGlobalTestReport(type: JacocoReport,
    dependsOn: [':app:createUiTestReport', ':submodule:createUnitTestReport']) {

reports {
    html.enabled = true
}

def fileFilter = [
        //Android stuff
        '**/R.class',
        '**/BR.class',
        '**/R$*.class',
        '**/BR$*.class',
        '**/BuildConfig.*',
        'Android/**/*.*',
        //Data Binding
        '**/*databinding',
        '**/*binders',
        '**/*layouts',
        '**/Manifest*.*',
        '**/*Test*.*'
]

//To support Java coverage on Unit tests
def debugAppTree = fileTree(dir: "${buildDir}/intermediates/classes/automationTest", excludes: fileFilter)
//To support Kotlin coverage on Unit tests
def debugKotlinAppTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/automationTest", excludes: fileFilter)

def debugSdkTree = fileTree(dir: "../submodule/build/intermediates/classes/automationTest", excludes: fileFilter)
def debugKotlinSdkTree = fileTree(dir: "../submodule/build/tmp/kotlin-classes/automationTest", excludes: fileFilter)


def mainAppSrc = "${project.projectDir}/src/main/Java"
def debugAppSrc = "${project.projectDir}/src/debug/Java"

def mainSdkSrc = "../submodule/src/main/Java"
def debugSdkSrc = "../submodule/src/debug/Java"


sourceDirectories = files([mainAppSrc, debugAppSrc,
                           mainSdkSrc, debugSdkSrc])

classDirectories = files([debugAppTree, debugSdkTree,
                          debugKotlinAppTree, debugKotlinSdkTree])

def appAndroidTests = fileTree(dir: "${buildDir}/outputs/code-coverage/connected/", includes: ["*.ec"])

executionData = files("${buildDir}/jacoco/testAutomationTestUnitTest.exec"
        , "../submodule/build/jacoco/testAutomationTestUnitTest.exec"
        , appAndroidTests
)
}
3
djrsousa

Palantirのプラグインを使用して、さまざまなモジュールの集計カバレッジレポートを作成します com.palantir.jacoco-full-report

基本的に、ルートgradleファイルで、これを依存関係に追加する必要があります。

classpath 'com.palantir:jacoco-coverage:0.4.0'

その後、./gradlew test jacocoFullReportを実行すると、build/reports/jacoco/jacocoFullReport/で、結合されたすべてのサブプロジェクトによって生成されたカバレッジを評価するテストレポートが作成されます。

0
Santoshastagi