Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jacoco和单元测试使用android gradle插件的代码覆盖率>;=1.1_Android_Unit Testing_Android Gradle Plugin_Jacoco - Fatal编程技术网

Jacoco和单元测试使用android gradle插件的代码覆盖率>;=1.1

Jacoco和单元测试使用android gradle插件的代码覆盖率>;=1.1,android,unit-testing,android-gradle-plugin,jacoco,Android,Unit Testing,Android Gradle Plugin,Jacoco,我最近开始在我的一个项目中集成安卓gradle插件1.1.0。该项目使用robolectric 2.4运行单元测试 这是一个具有非常复杂依赖关系的多模块项目(某些模块依赖于其他模块)。诸如此类: --> application-module (dependsOn: module1, module2, module-core) --> module1 (dependsOn: module-core) --> module2 (dependsOn: module-c

我最近开始在我的一个项目中集成安卓gradle插件
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为单元测试生成报告,但在我看来,它只运行
androidTests
,基本上是仪器测试

在谷歌搜索之后,我在GitHub和其他文章中遇到了一些项目,但它们主要关注的是以前版本的
android gradle插件
,或者正在使用其他第三方插件,如
android单元测试

也许我已经失去了谷歌搜索的能力。但是有人能告诉我一个方向吗?在那里我可以找到一些关于android gradle插件中的新东西的文档,以及如何只为单元测试运行jacoco任务

更新

采用了以下脚本:

同样的问题,生成了报告,但代码覆盖率仍然为零

更新_3

它表明,来自UPDATE_2的任务有效,但仅适用于带有
apply plugin:'com.android.application'
的模块(报告正确生成)。但是对于android库的模块(
apply plugin:'com.android.library'
),报告显示覆盖率为零,尽管模块包含的测试比应用程序模块更多

更新_4

创建了一个简单的示例项目来演示我的问题。当前,如果运行
/gradlew jacocoReport
,则会生成报告,但不会显示模块项目的测试覆盖率。看到这个了吗

简短说明:当测试是AndroidUnitTests(省略JUnit4和Robolectric)时,JaCoCo报告显示覆盖了所有模块


有什么想法吗?

警告:这是一个黑客!使用上面的配置,我根据选择的构建任务在应用程序和库之间切换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工具团队能尽快解决这个问题。

请创建一个示例,我可以看一下。我猜是路径配置缺失

  • 包括所有覆盖范围文件(*.exec)
  • 添加所有源路径(module/src/main/java)
  • 添加所有类路径(模块/构建/中间层/类/调试)
这里有两个例子说明它的外观


我与JaCoCo解决问题,并使其与最新的gradle android插件1.1.3配合使用

具有最新gradle脚本的项目:

参考资料:

如何在Android Studio单元测试中附加自己的实现而不是模拟?

对于尝试在android构建中使用JaCoCo覆盖的所有人的小提示。。。意外发现

用于单元测试的JaCoCo XML/HTML报告


我终于能够在AndroidStudio 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('$$', '$'))
            }
        }
    }
}
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'
然后在模块的build.gradle文件中(我把它放在
android
dependencies
之间):

同样在
android
defaultConfig
块中。我添加了这个(不知道是否有必要,但我从以下网站获得):


享受。

我和你面临着完全相同的问题。今天我完全删除了android studio、android sdk和gradle。然后重新安装一切。之后,我在应用程序build.gradle中添加了

调试{ testCoverageEnabled true }
然后我运行。/gradlew connectedChec。一切都很顺利。Android studio默认Jacoco对我来说运行良好。我认为也可以创建一个JacoTestReport任务,然后创建代码覆盖率。我不知道为什么gradle和android studio以前没有工作。

经过一些额外的搜索后,我偶然发现了这一点 我不得不做一些修改,这样解决方案才能适用于我的项目类型,但现在测试覆盖率报告已经正确生成


我已将所采用的更改推送到我的系统中,以防将来有人会遇到类似的问题。

我使用此设置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.*'
]

此外,单元测试的代码覆盖率可能会在将来内置

您可以尝试使用此Gradle插件:

基本上,您需要做的就是这样应用它:

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

在争论之后,我决定为此创建一个新的解决方案

根构建。渐变

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('$$', '$'))
            }
        }
    }
}
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输出

它还支持口味。将创建红色和蓝色两种颜色的任务

  • jacocoTestReportRedDebug
  • jacocoTestReportBlueDebug
  • jacocoTestReportRedRelease
  • jacocoTestReportBlueRelease

我在1.1-rc1中遇到了类似的情况(不可靠)。现在我正在运行1.1决赛,只会出现错误。期待其他回应。gradle android的相关问题:似乎您正在尝试为多项目设置生成覆盖率?我以前也有类似的问题
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