Gradle Jacoco can't mix test and integration reports


(Hristo Kostov) #1

Hi Guys,

We need some help to mix the reports from integration and unit tests.
I share a snippet of build.gradle:

apply plugin: 'java'
apply plugin: 'jacoco'

    configurations {
        itestCompile.extendsFrom testCompile
        itestRuntime.extendsFrom testRuntime
    }

    sourceSets {
        itest {
            java {
                compileClasspath += main.output + test.output
                runtimeClasspath += main.output + test.output
                srcDir file('src/itest/java')
            }
            resources.srcDir file('src/itest/resources')
        }
    }

    test {
        testLogging {
            events "passed", "skipped", "failed"
        }
    }

    task itest(type: Test) {
        reports.html.destination = file("$buildDir/reports/tests")
        //testReportDir = file("$buildDir/reports/tests/")
        //testResultsDir = file("$buildDir/test-results/")

        testClassesDir = sourceSets.itest.output.classesDir
        classpath = sourceSets.itest.runtimeClasspath
        systemProperties = System.properties
        // This is not needed, but it shows which tests have run
        testLogging {
            events "passed", "skipped", "failed"
        }
        jacoco {
            destinationFile = file("$buildDir/jacoco/IT/jacocoIT.exec")
            classDumpFile = file("$buildDir/jacoco/IT/classpathdumps")
        }


    }

    tasks.withType(Test) {
        reports.html.destination = file("${reporting.baseDir}/${name}")
    }

    // It is done to run integration tests after unit tests in task build
    itest.mustRunAfter test

    ext {
        limits = [
                'instruction': 93,
                'branch'     : 88,
                'line'       : 91,
                'complexity' : 84,
                'method'     : 87,
                'class'      : 95 //TODO - 100%
        ]
    }

    jacocoTestReport {

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

        afterEvaluate {
            classDirectories = files(classDirectories.files.collect {
                fileTree(dir: it,
                        exclude: ['**/*Dto*.class',
                                  '**/*Entity*.class',
                                  '**/*Test*.class',
                                  '**/commons/**/*.class',
                                  '**/security/**/*.class'])
            })
        }

        doLast {
            def report = file("${jacoco.reportsDir}/test/jacocoTestReport.xml")
            logger.lifecycle("Checking coverage results: ${report}")

            def parser = new XmlParser()
            parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            parser.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false)
            def results = parser.parse(report)

            def percentage = {
                def covered = it.'@covered' as Double
                def missed = it.'@missed' as Double
                ((covered / (covered + missed)) * 100).round(2)
            }

            def counters = results.counter
            def metrics = [:]
            metrics << [
                    'instruction': percentage(counters.find { it.'@type'.equals('INSTRUCTION') }),
                    'branch'     : percentage(counters.find { it.'@type'.equals('BRANCH') }),
                    'line'       : percentage(counters.find { it.'@type'.equals('LINE') }),
                    'complexity' : percentage(counters.find { it.'@type'.equals('COMPLEXITY') }),
                    'method'     : percentage(counters.find { it.'@type'.equals('METHOD') }),
                    'class'      : percentage(counters.find { it.'@type'.equals('CLASS') })
            ]


            def failures = []
            metrics.each {
                def limit = limits[it.key]
                if (it.value < limit) {
                    failures.add("- ${it.key} coverage rate is: ${it.value}%, minimum is ${limit}%")
                }
            }

            if (failures) {
                logger.quiet("------------------ Code Coverage Failed -----------------------")
                failures.each {
                    logger.quiet(it)
                }
                logger.quiet("---------------------------------------------------------------")
                throw new GradleException("Code coverage failed")
            } else{
                logger.quiet("Passed Code Coverage Checks")
            }
        }
        additionalSourceDirs = files(sourceSets.main.allJava.srcDirs)
    }

    check.dependsOn itest
    check.dependsOn jacocoTestReport

    // Returns the Gradle home folder. Used for development purposes.
    task getHomeDir << {
        println gradle.gradleHomeDir
    }

    run {
        systemProperties = System.properties
    }

In this situation it works pretty shine for all the unit tests but integration tests are missed in the calculations.
Could you help me how to add test reports to be taken in count?

Thanks in advance!