当前位置: 首页 > 知识库问答 >
问题:

多模块Android项目中的全局代码覆盖率:合并代码覆盖率报告(单元和UI测试)

潘修为
2023-03-14

我有一个Android应用程序,它由两个模块组成:

注意:我使用的是Gradle版本3.1.2。

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']
    }

    ...
apply plugin: 'jacoco'

android {

   testBuildType "uiTest"

   buildTypes {
    debug {
    }

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

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

  ...
}

我尝试了几种方法,下面这个确实合并了测试…但是报道并不正确:

//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)

//单元测试覆盖过滤

任务createTestReport(类型:JacocoReport,Dependson:['test UnitteStunitTest']){

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")

}

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
)

}

如有任何帮助,将不胜感激

共有1个答案

易弘阔
2023-03-14

我不确定它是否适用于多种构建类型。

尝试将其合并到单个构建类型中,并且:

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']
    }
    ...
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
)
}
 类似资料:
  • 我有这样的项目结构: 模块应用程序 模块-登录 模块注册 问题:我有上面喜欢Android项目的结构,能够生成jaco代码覆盖率报告,并且可以用于声纳仪表板。我面临的espresso测试问题,它只显示模块应用程序的代码覆盖率,而不显示其他模块的代码覆盖率。Espresso测试正在运行用例流,如注册,然后从其他两个模块登录和调用类,但其他两个模块的覆盖率始终为0%。 < li >我想了解espres

  • 新的一年 之前因为上家公司的经营出了问题,年前的大裁员,过了一个漫长的春节。 之后加入了新公司,然后正好赶上一个很紧急的项目,忙成狗,因此好久没更新文章了。 不过,我又回来啦! 前言 自动化测试,我们将使用karma和nightmare,内容会包括: 单元测试 e2e测试(放下一篇文章) 其实,单元测试一般用在写公共包的时候,比如通用的js函数库,通用的UI组件库。基本不太会在做业务项目的时候还使

  • 这是一个重要的可量化指标,如果代码覆盖率很高,你就可以放心的修改代码,在发版本的时候也能睡个安稳觉。否则就是拆东墙补西墙,陷入无尽的 bug 诅咒中。 那么在 OpenResty 里面如何看到代码覆盖率呢?其实很简单,使用 LuaCov 可以很方便的实现。 我们先了解下 LuaCov,这是一个针对 Lua 脚本的代码覆盖率工具,通过 luarocks 来安装: luarocks install l

  • 免责声明初学者问题! 为了回答这个问题,我的项目结构高度简化,如下所示: 在阅读了Jeff Knupp关于单元测试的博客文章并写了一系列测试之后,我想看看我的代码现在被测试覆盖了多少。所以我安装了coverage.py,以下内容让我困惑: $coverage运行main。py(显示脚本中的打印/日志) $覆盖报告main.py 姓名、Stmts、小姐、封面 主要的py,114,28,75% 问题是

  • Jacoco插件在jenkins报告中显示0%的覆盖率,但当我在本地系统中运行相同的命令时,Jacoco会正确生成报告。我正在使用以下命令: mvn-s xyz/settings.xml-f xyz/xyz/pom.xml清洁安装org.jacoco 所以当我在jenkins中运行这个命令时,它会生成错误的报告。我已经检查了它在工作区目录对应的项目在詹金斯。它显示每个项目的0%覆盖率。但是当我在本

  • 我有一个maven多模块项目。 所有测试都在称为tests/的单个模块中,所有代码都在单独的模块中。 有没有办法让我得到代码覆盖率?