【问题标题】:Gradle Jacoco test coverage for integration test across sub modules跨子模块集成测试的 Gradle Jacoco 测试覆盖率
【发布时间】:2020-02-28 10:05:27
【问题描述】:

我的项目结构如下,

--项目
--道
--服务
--控制器
--测试
--build.gradle.kts

我在控制器中只有集成测试。我所有的子模块(DAO、服务和控制器)都是 gradle 项目,其中包含 build.gradle.kts。

以下是我的父模块中的 build.gradle.kts,即在项目中

import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

val Project.`java`: JavaPluginConvention
    get() = convention.getPluginByName("java")

plugins {
    val kotlinVersion = "1.3.61"
    val testLoggerVersion = "1.6.0"
    val dokkaVersion = "0.9.18"

    base
    jacoco
    kotlin("jvm") version kotlinVersion apply false
    maven
    id("com.adarshr.test-logger") version testLoggerVersion apply false
    id("org.jetbrains.dokka") version dokkaVersion apply false
}

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

allprojects {
    version = "dev"

    repositories {
        jcenter()
        mavenCentral()
    }
}

subprojects {
    apply {
        plugin("kotlin")
        plugin("jacoco")
        plugin("com.adarshr.test-logger")
        plugin("org.jetbrains.dokka")
    }

    dependencies {
        "implementation"(kotlin("stdlib"))
        "implementation"("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinxCoroutinesVersion")

        "implementation"("com.fasterxml.jackson.module:jackson-module-kotlin:$fasterxmlVersion")
        "implementation"("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$fasterxmlVersion")
        "implementation"("org.koin:koin-core:$koinVersion")

        "testImplementation"("org.koin:koin-test:$koinVersion")
        "testImplementation"("io.mockk:mockk:$mockkVersion")
        "testImplementation"("org.junit.jupiter:junit-jupiter-api:$jUnitVersion")
        "testImplementation"("org.junit.jupiter:junit-jupiter-params:$jUnitVersion")
        "testImplementation"("org.testcontainers:junit-jupiter:$testcontainersVersion")
        "testImplementation"("org.testcontainers:testcontainers:$testcontainersVersion")
        "testImplementation"("org.testcontainers:postgresql:$testcontainersVersion")
        "testRuntime"("org.junit.jupiter:junit-jupiter-engine:$jUnitVersion")
    }

    tasks.register<Jar>("uberJar") {
        archiveClassifier.set("uber")
        from(java.sourceSets["main"].output)

        dependsOn(configurations["runtimeClasspath"])

        from({
            configurations["runtimeClasspath"]
                .filter { it.name.endsWith("jar") }
                .map { zipTree(it) }
        })
    }

    tasks.register<Zip>("uberZip") {
        from(java.sourceSets["main"].output)

        dependsOn(configurations["runtimeClasspath"])
        from({
            configurations["runtimeClasspath"]
                .filter { it.name.endsWith("jar") }
                .map { zipTree(it) }
        })
    }

    tasks.withType<DokkaTask> {
        outputFormat = "html"
        outputDirectory = "$buildDir/javadoc"
    }

    tasks.withType<KotlinCompile> {
        sourceCompatibility = javaVersion
        targetCompatibility = javaVersion

        kotlinOptions {
            jvmTarget = javaVersion
            apiVersion = kotlinVersion
            languageVersion = kotlinVersion
        }
    }

    tasks.withType<JacocoReport> {
        reports {
            html.apply {
                isEnabled = true
                destination = file("$buildDir/reports/jacoco")
            }
            csv.isEnabled = false
        }

        afterEvaluate {
            classDirectories.setFrom(files(classDirectories.files.map {
                fileTree(it).apply {
                    exclude("io/company/common/aws/test/support/**")
                    exclude("io/company/common/system/**")
                }
            }))
        }
    }

    tasks.withType<Test> {
        useJUnitPlatform()
        testLogging.showStandardStreams = true
        testLogging {
            events("PASSED", "FAILED", "SKIPPED", "STANDARD_OUT", "STANDARD_ERROR")
        }
    }


}

我的问题是 jacoco 代码覆盖率。当我运行./gradlew clean test jacocoTestReport 时,我只得到我的控制器而不是服务和 daos 的覆盖范围。

我的 gradle 版本是 5.4.1。

如何获得涵盖所有测试模块的测试覆盖率综合报告? 我尝试了来自 stackoverflow 的多个链接,但没有运气。

【问题讨论】:

    标签: gradle jacoco


    【解决方案1】:

    您可以为此使用 JacocoMerge 任务,该任务是为该用例明确创建的。它将获取子项目的各个报告并将它们合并为一个报告。将以下 sn-p 添加到您的根项目并在必要时进行调整。

    val jacocoMerge by tasks.registering(JacocoMerge::class) {
        subprojects {
            executionData(tasks.withType<JacocoReport>().map { it.executionData })
        }
        destinationFile = file("$buildDir/jacoco")
    }
    
    tasks.register<JacocoReport>("jacocoRootReport") {
        dependsOn(jacocoMerge)
        sourceDirectories.from(files(subprojects.map {
            it.the<SourceSetContainer>()["main"].allSource.srcDirs
        }))
        classDirectories.from(files(subprojects.map { it.the<SourceSetContainer>()["main"].output }))
        executionData(jacocoMerge.get().destinationFile)
        reports { // <- adjust
            html.isEnabled = true
            xml.isEnabled = true
            csv.isEnabled = false
        }
    }
    

    现在gradle jacocoRootReport 将为您提供全面覆盖。

    【讨论】:

    • 嘿 Arvid,我在 DAO 和 Service 中没有任何测试,这还能用吗?控制器中的测试正在调用所有这些子模块,因此我需要从控制器的测试中完成覆盖。
    • 如果只是为 jacoco 报告添加类,则不需要新任务,只需修改现有 jacoco 任务的 sourceDirectoriesclassDirectories,方式与我的 sn- p.
    • 我将destinationFile 更改为destinationFile = file("$buildDir/jacoco/test.exec") 并重新运行'gradle jacocoRootReport' 但得到> 没有为属性'executionData' 指定值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    相关资源
    最近更新 更多