首页 > 解决方案 > SonarQube 仅在最多使用一个 android 仪器测试时才有效

问题描述

我关注了这个博客:在这里为我的 Android 应用程序设置 SonarQube 和 Jacoco。我想获得单元测试和仪器测试的代码覆盖率。单元测试工作正常,如果我有一个仪器测试并且它也会被报告。但是,只要我添加另一个仪器测试,就不会报告任何仪器测试。

这是我的 sonarQube.gradle:

apply plugin: "org.sonarqube"

sonarqube {
    properties {
        property "sonar.host.url", "[...]"
        property "sonar.projectKey", projectKey
        property "sonar.projectName", projectName

        property "sonar.projectVersion", "${android.defaultConfig.versionName}"

        property "sonar.junit.reportsPath", "build/test-results/testDebugUnitTest"
        property "sonar.java.coveragePlugin", "jacoco"
        property "sonar.sourceEncoding", "UTF-8"
        property "sonar.android.lint.report", "build/reports/lint-results.xml"
        property "sonar.jacoco.reportPaths", "build/jacoco/testDebugUnitTest.exec"
        println "itReportPath: ${fileTree(dir: project.projectDir, includes: ["**/*.ec"])}"
        property "sonar.jacoco.itReportPath", fileTree(dir: project.projectDir, includes: ["**/*.ec"])
        property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/testDebugUnitTestCoverage/testDebugUnitTestCoverage.xml"
        
    }
}
tasks.sonarqube.dependsOn ":app:testDebugUnitTestCoverage"

这是我的 jacoco.gradle:

apply plugin: 'jacoco'

jacoco {
    toolVersion = "0.8.6"
    // Custom reports directory can be specfied like this:
    // reportsDir = file("$buildDir/customJacocoReportDir")
}

tasks.withType(Test) {
    jacoco.includeNoLocationClasses = true
    jacoco.excludes = ['jdk.internal.*']
    // see related issue https://github.com/gradle/gradle/issues/5184#issuecomment-457865951
}

project.afterEvaluate {
    (android.hasProperty('applicationVariants')
        ? android.'applicationVariants'
        : android.'libraryVariants')
        .all { variant ->
            def variantName = variant.name
            def unitTestTask = "test${variantName.capitalize()}UnitTest"
            def androidTestCoverageTask = "create${variantName.capitalize()}CoverageReport"

            tasks.create(name: "${unitTestTask}Coverage", type: JacocoReport, dependsOn: [
                    "$unitTestTask",
                    "$androidTestCoverageTask"
            ]) {

                group = "Reporting"
                description = "Generate Jacoco coverage reports for the ${variantName.capitalize()} build"

                reports {
                    html.enabled = true
                    xml.enabled = true
                    csv.enabled = true
                }

                def excludes = [
                        // data binding
                        'android/databinding/**/*.class',
                        '**/android/databinding/*Binding.class',
                        '**/android/databinding/*',
                        '**/androidx/databinding/*',
                        '**/BR.*',
                        // android
                        '**/R.class',
                        '**/R$*.class',
                        '**/BuildConfig.*',
                        '**/Manifest*.*',
                        '**/*Test*.*',
                        'android/**/*.*',
                        // butterKnife
                        '**/*$ViewInjector*.*',
                        '**/*$ViewBinder*.*',
                        // dagger
                        '**/*_MembersInjector.class',
                        '**/Dagger*Component.class',
                        '**/Dagger*Component$Builder.class',
                        '**/*Module_*Factory.class',
                        '**/di/module/*',
                        '**/*_Factory*.*',
                        '**/*Module*.*',
                        '**/*Dagger*.*',
                        '**/*Hilt*.*',
                        // kotlin
                        '**/*MapperImpl*.*',
                        '**/*$ViewInjector*.*',
                        '**/*$ViewBinder*.*',
                        '**/BuildConfig.*',
                        '**/*Component*.*',
                        '**/*BR*.*',
                        '**/Manifest*.*',
                        '**/*$Lambda$*.*',
                        '**/*Companion*.*',
                        '**/*Module*.*',
                        '**/*Dagger*.*',
                        '**/*Hilt*.*',
                        '**/*MembersInjector*.*',
                        '**/*_MembersInjector.class',
                        '**/*_Factory*.*',
                        '**/*_Provide*Factory*.*',
                        '**/*Extensions*.*',
                        // sealed and data classes
                        '**/*$Result.*',
                        '**/*$Result$*.*'
                ]

                def javaClasses = fileTree(dir: variant.javaCompileProvider.get().destinationDir,
                        excludes: excludes)
                def kotlinClasses = fileTree(dir: "${buildDir}/tmp/kotlin-classes/${variantName}",
                        excludes: excludes)

                classDirectories.setFrom(files([
                        javaClasses,
                        kotlinClasses
                ]))

                def variantSourceSets = variant.sourceSets.java.srcDirs.collect { it.path }.flatten()
                sourceDirectories.setFrom(project.files(variantSourceSets))

                def androidTestsData = fileTree(dir: "${buildDir}/outputs/code_coverage/${variantName}AndroidTest/connected/", includes: ["**/*.ec"])

                executionData(files([
                        "$project.buildDir/jacoco/${unitTestTask}.exec",
                        androidTestsData
                ]))
            }
        }
}

链接的博客提到您必须使用 gradle 6.3,但即使使用 gradle 6.3,我也会得到所描述的行为。

我该如何解决这个问题?

标签: androidgradlesonarqubejacoco

解决方案


推荐阅读