【问题标题】:Gradle task jacoco report generate empty html report file (No class files specified)Gradle 任务 jacoco 报告生成空的 html 报告文件(未指定类文件)
【发布时间】:2019-09-07 12:51:19
【问题描述】:

我想使用 Jacoco 为我的所有测试(androidTest + UnitTest)生成代码覆盖率报告。

所以我实现了一个分步脚本 (jacoco.gradle) 来创建一个任务,该任务允许我生成一个合并两个代码覆盖率报告的报告。

我的问题是html生成的文件是空的(在app\build\jacocoReport\index.html):

没有指定类文件。 JaCoCo 0.8.3.201901230119

我执行“testIntegrationDebugUnitTest”任务:

  • androidTest 代码覆盖率报告已在 app/build/reports/coverage/integration/debug/index.html 上创建,一切正常。

  • 已在 app\build\outputs\code_coverage\integrationDebugAndroidTest\connected\Pixel_2_API_24(AVD) - 7.0-coverage.ec 上生成“ec”文件

  • 已在 app/build/jacoco/testIntegrationDebugUnitTest.exec 上生成了一个“exec”文件

你知道我的问题来自哪里吗?这是我的代码:

jacoco.gradle:

apply plugin: 'jacoco'

jacoco {
    toolVersion = "$jacocoVersion"
    reportsDir = file("$buildDir/jacocoReport")
}

project.afterEvaluate {

    android.applicationVariants.all { variant ->
        def variantName = variant.name
        def testTaskName = "test${variantName.capitalize()}UnitTest"
        def androidTestCoverageTaskName = "create${variantName.capitalize()}CoverageReport"

        tasks.create(name: "${testTaskName}Coverage", type: JacocoReport, dependsOn: ["$testTaskName", "$androidTestCoverageTaskName"]) {
            group = "Reporting"
            description = "Generate Jacoco coverage reports for the ${variantName.capitalize()} build."

            reports {
                xml.enabled = false
                html.enabled = true
                html.destination "$buildDir/jacocoReport"
            }

            def excludes = ['**/R*.class',
                            '**/*$InjectAdapter.class',
                            '**/*$ModuleAdapter.class',
                            '**/*$ViewInjector*.class'
            ]

            def debugTree = fileTree(dir: "$project.buildDir/intermediates/javac/debug", excludes: excludes)
            def mainSrc = "$project.projectDir/src/main/java"

            sourceDirectories = files([mainSrc])
            classDirectories = files([debugTree])
            executionData = fileTree(dir: project.buildDir, includes: [
                    "jacoco/${testTaskName}.exec", "outputs/code_coverage/${variantName}AndroidTest/connected/**/*.ec"
            ])
        }
    }
}

gradle 项目:

buildscript {
    ext.kotlin_version = '1.3.21'
    ext.jacocoVersion = '0.8.3'

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'io.realm:realm-gradle-plugin:5.8.0'
        classpath 'com.google.gms:google-services:4.2.0'
        classpath 'io.fabric.tools:gradle:1.28.0'
        classpath "org.jacoco:org.jacoco.core:$jacocoVersion"
    }
}

task installGradle(type: Wrapper) {
    group = "*********"
    gradleVersion = '4.10.1'
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

应用分级:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'io.fabric'
apply from: '../scripts/jacoco.gradle'

android.applicationVariants.all { variant ->
    if (variant.name == 'demoDebug' || variant.name == 'evalDebug' || variant.name == 'stagingDebug') {
        project.tasks.getByName('process' + variant.name.capitalize() + 'GoogleServices').enabled = false
        project.tasks.getByName('fabricGenerateResources' + variant.name.capitalize()).enabled = false
    }
}

android {

    compileSdkVersion 28
    defaultConfig {
        applicationId "***********"
        minSdkVersion 23
        targetSdkVersion 28
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    buildTypes {
        debug {
            testCoverageEnabled true
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'android.arch.lifecycle:extensions:1.1.1'
    implementation 'com.google.firebase:firebase-core:16.0.8'
    implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'

    testImplementation 'junit:junit:4.12'
    testImplementation 'org.mockito:mockito-core:2.25.1'
    testImplementation 'android.arch.core:core-testing:1.1.1'

    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    androidTestImplementation 'org.mockito:mockito-android:2.25.1'
    androidTestImplementation 'android.arch.core:core-testing:1.1.1'
}

【问题讨论】:

  • 我没有 InstrumentationResultParser 错误,也没有其他错误。我只有一个空的 html。
  • 报告显示No class files specified,这是构建工具28.0.3 和$project.buildDir/intermediates/javac/debug。曾经检查过*.class 中是否存在任何debugTree 文件?
  • 我遇到了同样的问题。对我有用的是将debugTree def 更改为:def debugTree = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/debug", excludes: excludes)
  • @MatPag 应该作为答案发布;谢谢,对我有用

标签: android gradle kotlin code-coverage jacoco


【解决方案1】:

这是一个常见问题,需要将debugTree属性改为:

//java compiled classes
def javaTree = fileTree(dir: "$project.buildDir/intermediates/javac/debug/classes", excludes: fileFilter)
//kotlin compiled classes
def kotlinTree = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)
//...etc...
classDirectories.from = files([javaTree, kotlinTree])

debug 可以是任何变体,如果您知道自己在做什么,可以使用$variantName 代替它

【讨论】:

  • 我猜它只包含 kotlin 类。如果你有一个混合了 Java 和 Kotlin 的代码库,它可能会错过一些 Java 文件的覆盖范围。
  • @BenPearson 是的,用户对 kotlin 特别感兴趣,顺便说一句,我已经更新了我的答案以涵盖 Java 和 Kotlin 源
  • 感谢您的更新!那很快。这是一个 Android 项目,因此可以同时包含 Kotlin 和 Java;我认为您的答案现在涵盖了所有基础。
【解决方案2】:

你是否用maven配置了jacoco插件,如果是请检查配置标签的路径。应该是target/classes目录的类路径,而不是包路径。

【讨论】:

  • 这应该是评论,而不是答案
猜你喜欢
  • 2018-12-18
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-20
相关资源
最近更新 更多