Gradle Jacoco跨子模块集成测试覆盖率

Gradle Jacoco跨子模块集成测试覆盖率,gradle,jacoco,Gradle,Jacoco,我的项目结构如下: --项目 --Dao --服务 --控制器 --测试 --build.gradle.kts 我在控制器中只有集成测试。我的所有子模块(DAO、服务和控制器)都是gradle项目,其中包含build.gradle.kts 以下是我在父模块(即项目内部)中的build.gradle.kts import org.jetbrains.dokka.gradle.DokkaTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompi

我的项目结构如下:

--项目
--Dao
--服务
--控制器
--测试
--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")
        }
    }


}
import org.jetbrains.dokka.gradle.DokkaTask
导入org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val项目.`java`:JavaPluginConvention
get()=convention.getPluginByName(“java”)
插件{
val kotlinVersion=“1.3.61”
val testLoggerVersion=“1.6.0”
val dokkaVersion=“0.9.18”
基础
杰科科
kotlin(“jvm”)版本kotlin应用错误
专家
id(“com.adarshr.test logger”)版本testLoggerVersion apply false
id(“org.jetbrains.dokka”)版本dokkaVersion应用false
}
杰科科{
toolVersion=jacocoVersion
reportsDir=file($buildDir/reports/jacoco)
}
所有项目{
version=“dev”
存储库{
jcenter()
mavenCentral()
}
}
子项目{
申请{
插件(“kotlin”)
插件(“jacoco”)
插件(“com.adarshr.testlogger”)
插件(“org.jetbrains.dokka”)
}
依赖关系{
“实施”(kotlin(“stdlib”))
“实现”(“org.jetbrains.kotlinx:kotlinx协程核心:$kotlinxCoroutinesVersion”)
“实现”(“com.fasterxml.jackson.module:jackson module kotlin:$fasterxmlVersion”)
“实现”(“com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$fasterxmlVersion”)
“实现”(“org.koin:koin核心:$koin”)
“测试实施”(“org.koin:koin-test:$koin”)
“测试实现”(“io.mockk:mockk:$mockkVersion”)
“测试实现”(“org.junit.jupiter:junit-jupiter-api:$jUnitVersion”)
“测试实现”(“org.junit.jupiter:junit-jupiter参数:$jUnitVersion”)
“testImplementation”(“org.testcontainers:JUnitJupiter:$TestContainerVersion”)
“testImplementation”(“org.testcontainers:testcontainers:$TestContainerVersion”)
“testImplementation”(“org.testcontainers:postgresql:$TestContainerVersion”)
“testRuntime”(“org.junit.jupiter:junit-jupiter引擎:$jUnitVersion”)
}
任务。注册(“uberJar”){
archiveClassifier.set(“uber”)
from(java.sourceset[“main”].output)
dependsOn(配置[“runtimeClasspath”])
从({
配置[“runtimeClasspath”]
.filter{it.name.endsWith(“jar”)}
.map{zipTree(it)}
})
}
任务。注册(“uberZip”){
from(java.sourceset[“main”].output)
dependsOn(配置[“runtimeClasspath”])
从({
配置[“runtimeClasspath”]
.filter{it.name.endsWith(“jar”)}
.map{zipTree(it)}
})
}
tasks.withType{
outputFormat=“html”
outputDirectory=“$buildDir/javadoc”
}
tasks.withType{
sourceCompatibility=javaVersion
targetCompatibility=javaVersion
科特洛普斯酒店{
jvmTarget=javaVersion
apiVersion=Kotl反转
languageVersion=Kotl反转
}
}
tasks.withType{
报告{
html.apply{
isEnabled=true
目标=文件($buildDir/reports/jacoco)
}
csv.isEnabled=false
}
后评价{
classDirectories.setFrom(文件)(classDirectories.files.map{
文件树(it).apply{
排除(“io/company/common/aws/test/support/**”)
排除(“io/company/common/system/**”)
}
}))
}
}
tasks.withType{
useJUnitPlatform()
testLogging.showStandardStreams=true
测试记录{
事件(“通过”、“失败”、“跳过”、“标准输出”、“标准错误”)
}
}
}
我的问题是jacoco代码覆盖率。当我运行
/gradlew clean test jacocoTestReport
时,我只覆盖我的控制器,而不覆盖服务和DAO

我的gradle版本是5.4.1

我如何才能获得涵盖所有测试模块的测试覆盖率综合报告?? 我尝试了stackoverflow中的多个链接,但没有成功。

您可以使用该任务,它是为该用例显式创建的。它将获取子项目的各个报告,并将它们合并到一个报告中。将以下代码段添加到根项目中,并在必要时进行调整

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
    }
}
val jacocoMerge by tasks.注册(jacocoMerge::class){
子项目{
executionData(tasks.withType().map{it.executionData})
}
destinationFile=file($buildDir/jacoco)
}
任务。注册(“jacocoRootReport”){
德彭森(杰科科科梅)
sourceDirectories.from(文件)(subprojects.map{
it.the()[“main”].allSource.srcDirs
}))
classDirectories.from(文件(subprojects.map{it.the()[“main”].output}))
executionData(jacoComge.get().destinationFile)

报告{//Hey Arvid,我在DAO和服务中没有任何测试,这仍然有效吗?控制器中的测试正在调用所有这些子模块,因此我需要完成控制器测试的覆盖范围。如果只是向jacoco报告添加类,您不需要新任务,只需要修改
源目录
classDirec以与我的代码片段中相同的方式保留现有jacoco任务的
。我将destinationFile更改为destinationFile=file($buildDir/jacoco/test.exec),并重新运行“gradle JacoRootReport”,但未为属性“executionData”指定任何值