[JAVA] Output JaCoCo coverage to console

If you're using GitLab CI, you can parse test coverage from console output and associate it with commits without having to work with external services such as Coveralls (https://coveralls.io/) or Jenkins ( Test coverage parsing is useful. However, the essential Gradle JaCoCo Plugin does not have the ability to output coverage to the console.

Here, we will introduce how to output test coverage to standard output by parsing the report XML file output by JaCoCo by yourself. For this method, I referred to the build file of SpringFox.

Operation confirmed version

Build file

Like this. Groovy isn't a big deal, so it's sloppy.

plugins {
    id 'jacoco'
}

jacocoTestReport {
    reports {
        xml.enabled = true
        html.enabled = true
    }
    doLast {
        def report = file("${jacoco.reportsDir}/test/jacocoTestReport.xml")
        printCoverage(report)
    }
}

test.finalizedBy jacocoTestReport

def printCoverage(File xml) {
    if (!xml.exists()) return

    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(xml)

    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 = [
            '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') })
    ]

    logger.quiet("----- Code Coverage ----------")
    metrics.each { key, value -> logger.quiet(sprintf(" - %-11s: %6.2f%%", key, value)) }
    logger.quiet("------------------------------")
}

Output image

You can see that the coverage is output to the console when you run the test.

$ ./gradlew test
...
> Task :jacocoTestReport
----- Code Coverage ----------
 - instruction:  27.32%
 - branch     :   3.50%
 - line       :  91.25%
 - complexity :  34.05%
 - method     :  72.94%
 - class      : 100.00%
------------------------------
...

Supplement

The JaCoCo report XML has the following format, so it looks for the top-level counter element of this XML and calculates the coverage from the values of missed and covered.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.0//EN" "report.dtd">
<report name="example">
    ...
    <counter type="INSTRUCTION" missed="931" covered="350" />
    <counter type="BRANCH" missed="193" covered="7" />
    <counter type="LINE" missed="7" covered="73" />
    <counter type="COMPLEXITY" missed="122" covered="63" />
    <counter type="METHOD" missed="23" covered="62" />
    <counter type="CLASS" missed="0" covered="9" />
</report>

Summary

The coverage function of GitLab CI does not have the advanced function of tracking the time transition of coverage like other services, but it can be displayed by linking the coverage to the commit quickly, so as a first step It's simple and good.

It sounds pretty niche, but if anyone wants to console coverage with JaCoCo, give it a try.

Recommended Posts

Output JaCoCo coverage to console
How to output Java string to console screen
How to color code console output in Eclipse
Output settings to debug console in Visual Studio Code
Output javadoc to word file
Output XML tree to file
How to exclude auto-generated from Jacoco coverage when using Lombok
Input to the Java console
Introduction to swift practice output Chapter5
Output test coverage with clover + gradle
Log output to file in Java
Enable log output to both file and console using log4j in Eclipse.