SpockFramework + Groovy 的 Jacoco 覆盖不完整

问题描述 投票:0回答:1

给定一个带有默认值的 case 语句,对此进行单元测试

  • 当 IDEA 运行覆盖测试时,这些行显示为已覆盖。
  • 当 gradle+jacoco 创建报告时,这些行显示为未覆盖。

Copilot 认为 groovy 编译器添加的额外字节代码可能会导致这种情况。不确定我是否相信鉴于我在搜索中看到的示例,但我还没有找到适合我的情况的解决方案。

如何让覆盖工具同意 groovy + SpockFramework 测试?

Jacoco 报道

IDEA 报道

构建.gradle

plugins {
    id 'com.jfrog.artifactory' version '5.0.3'
    id 'com.github.spotbugs' version '5.1.1'
    id 'org.sonarqube' version '4.4.1.3373'
    id 'org.ajoberstar.grgit' version '4.0.1'
    id 'jacoco'
    id 'groovy'
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

sourceSets {
    gdsl {
        groovy {
            srcDirs 'gdsl'
            compileClasspath = compileGroovy.classpath
        }
    }
    main {
        groovy {
            srcDirs = ['src', 'vars']
        }
    }
    test {
        groovy {
            srcDirs 'test/groovy'
        }
        resources {
            srcDirs = [ 'test/resources']
        }
    }
}

repositories {
...
}

tasks.withType(Test) {
    testLogging {
        showStandardStreams = true
        events "passed", "failed"
        displayGranularity = 1
    }
}

dependencies {
    implementation 'org.codehaus.groovy:groovy-all:2.4.21'
    implementation 'com.cloudbees:groovy-cps:1.32'
    implementation "org.jenkins-ci.main:jenkins-core:${jenkinsVersion}"
    implementation 'org.yaml:snakeyaml:2.2'

    // Spock Unit Test Support
    testImplementation platform("org.spockframework:spock-bom:1.3-groovy-2.4")
    testImplementation 'org.spockframework:spock-core'
    

    // pipeline unit support
    testImplementation 'com.lesfurets:jenkins-pipeline-unit:1.19'

    // junit support - mostly for junit @Rules
    testImplementation 'junit:junit:4.13.1'
}

tasks.withType(GroovyCompile) {
    options.debug = true
    options.compilerArgs = ['-g:lines,vars,source']
}

spotbugs {
    ignoreFailures = true
    showStackTraces = true
    showProgress = true
    effort = 'max'
    reportLevel = 'default'
    excludeFilter.set(file("${projectDir}/configuration/spotbugsExcludeFilter.xml"))
}

tasks.withType(com.github.spotbugs.snom.SpotBugsTask) {
    reports {
        xml {
            enabled = true
        }
        html {
            enabled = true
        }
    }
}

def gitBranch() {
    def branchName = "";
    def proc = "git rev-parse --abbrev-ref HEAD".execute();
    proc.in.eachLine { line -> branchName = line }
    proc.err.eachLine { line -> println line }
    proc.waitFor();
    return branchName;
}

jacoco {
    toolVersion = "0.8.11"
}

jacocoTestReport {
    reports {
        xml.required = true
        csv.required = false
    }

    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it,
                    include: ['vars/**', '**/mycorp/**']) // Exclude other directories if needed
        }))
    }

    dependsOn test // tests are required to run before generating the report
}

test {
    // use available processor resources
    maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1

    // set location for unit tests to have their "workspaces"
    systemProperty "testing.root.dir", "${project.buildDir.absolutePath}/working-test-dirs"
    systemProperty "project.root.dir", "${project.rootDir.absolutePath}"
    useJUnit()
    finalizedBy jacocoTestReport // report is always generated after tests run
}

task consumerGroovyDoc(type: Groovydoc) {
    source project.files('vars')
    docTitle = "Library Consumer Documentation"
    destinationDir = file("${project.buildDir}/docs/groovydoc/consumers")
    classpath = project.groovydoc.classpath
}

task internalsGroovyDoc(type: Groovydoc) {
    source project.files('src')
    docTitle = "Library Internals Documentation"
    destinationDir = file("${project.buildDir}/docs/groovydoc/internals")
    classpath = project.groovydoc.classpath
}

task generateGroovyDoc(dependsOn: [consumerGroovyDoc, internalsGroovyDoc]) {
}
tasks.build.finalizedBy tasks.generateGroovyDoc
gradle groovy spock jacoco
1个回答
0
投票

来自 Jacoco 常见问题解答

有异常的源代码行显示没有覆盖。为什么?

JaCoCo 使用所谓的探针确定代码执行。探针被插入到控制流的某些位置。当执行后续探测时,代码被视为已执行。如果出现异常,这样的指令序列会在中间的某个位置中止,并且相应的源代码行不会被标记为已覆盖。

© www.soinside.com 2019 - 2024. All rights reserved.