Make Java code coverage more comfortable with Jacoco 0.8.0

JaCoCo (hereafter referred to as jacoco) is a Java library for Java C0 (step) and C1 (branch) coverage and reporting.

jacoco is a very useful library, but there is a problem with some Java syntax that "clearly it passes in the test code, but it is treated as a mistake in coverage". However, with the recent release of jacoco 0.8.0, many issues have been resolved.

Summary

--By upgrading to Jacoco v0.8.0, the following C0 / C1 coverage of Java syntax introduced in JDK7 or later will work normally. --try-catch-resource clause --String switch statement --synchronized clause --In Maven, Gradle, it can be used by specifying the version of jacoco plugin to 0.8.0. --Jenkins jacoco plugin (as of v2.2.1) can only use 0.7.5, so 0.8.0 cannot be used. (It may be possible if you do a custom build)

background

Some Java syntax and Java bytecode of Java syntax introduced after JDK7 have unreachable routes that are not expressed in Java source code. Therefore, even if you write a test that can achieve 100% coverage of C0 / C1 at the Java source code level, there was a problem that C0 / C1 coverage could not be 100% for some reason.

jacoco 0.8.0 allows you to exclude these special unreachable Java bytecodes and properly measure the coverage of more Java source code.

Supplement: I think the validity of 100% C0 / C1 coverage is controversial. However, in some development work, there is a reality that you are getting money by satisfying this index, so it is necessary to make a compromise around this.

Main Java syntax supported by jacoco 0.8.0

Here, I will introduce the Java syntax that makes coverage work properly with jacoco 0.8.0. Of particular importance is the support for the try-catch-resource clause and the String switch statement.

1. try-catch-resource clause

The try-catch-resource clause is a Java syntax that is convenient for closing Reader etc. reliably and concisely. In versions prior to jacoco 0.8.0, coverage wasn't 100% unless you raised an "exception that slips through catch", but in jacoco 0.8.0 it's 100%.

public static void printFileContents(String fileName) {
    try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
        System.out.println(br.toString());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    //Supplement: 100 coverage%It is also necessary to execute the exception occurrence pattern that "passes through" in order to
}

See Issue # 500 for more information.

2. String switch statement

See Issue # 496 for details.

For example, in order to cover the coverage of the following source code, the coverage of C0 / C1 is not 100% even if the input patterns of A, B, C, and D are verified. With jacoco 0.8.0 this coverage is 100%.

public static boolean stringSwitch(String s) {
    switch(s) {
        case "A": break;
        case "B": break;
        case "C": break;
        default: break;
    }
}

Support status of build / CI related tools

Here, we will organize the support status of "jacoco version 0.8.0" of the jacoco plugin provided by Gradle, Maven, and Jenkins. Available except for Jenkins.

Gradle Conclusion: Any jacoco version available

Gradle provides the jacoco plugin as standard, but the jacoco version used by default is a bit outdated. Fortunately, you can specify the jacoco version with the jacoco plugin property toolVersion, so let's specify 0.8.0.

build.gradle(Excerpt)


apply plugin: 'jacoco'
jacoco {
    toolVersion = "0.8.0"
}

Maven Conclusion: Any jacoco version available

It corresponds like Gradle. The official jacoco documentation also has information about the jacoco plugin for Maven. In terms of jacoco, the Maven side seems to be the head family. http://www.eclemma.org/jacoco/trunk/doc/maven.html

pom.xml(Excerpt)


<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.0</version>
</plugin>

Jenkins Conclusion: Only jacoco 0.7.5 is available even with the latest version of jacoco plugin (v2.2.1)

The Jenkins jacoco plugin seems to be the last one with v2.0.0 and the jacoco version updated to v0.7.5. As far as checking the change history, the jacoco version has not been updated until the latest v2.2.1 at this time. In particular, unlike Gradle's jacoco plugin, you cannot specify the version, so you need to modify the source code.

In addition, since the master repository of GitHub has been updated to jacoco 0.8.0, it seems that jacoco 0.8.0 can be used if you build the plugin based on the source code of GitHub.

https://github.com/jenkinsci/jacoco-plugin/blob/master/pom.xml

jacoco-plugin/pom.xml(Excerpt)


<jacoco.version>0.8.0</jacoco.version>

(Bonus) Filtering related classes introduced in jacoco 0.8.0

The reason many Java syntax coverage issues have been resolved since jacoco 0.8.0 is the addition of filtering-related implementations of unreachable Java bytecode. In 2017, committer Godin introduced a mechanism to filter unreachable Java bytecodes in special cases, so that C0 / C1 coverage at the source code level can be judged normally.

With the introduction of this filtering-related class, it has become possible to filter Java bytecode roots that "cannot be reached at the Java source code level" on a case-by-case basis, and it has become possible to exclude parts that do not need to be counted as coverage. Perhaps we will continue to add filtering-related classes to handle cases where coverage cannot be performed normally.

Filter-related class files are located in the following directories on GitHub. org.jacoco.core.internal.analysis.filter

Recommended Posts

Make Java code coverage more comfortable with Jacoco 0.8.0
[JaCoCo (Java Code Coverage)] Use with NetBeans
Let's migrate to make Java more comfortable
Comfortable download with JAVA
Java build with mac vs code
Execute packaged Java code with commands
Prepare Java development environment with VS Code
Link Java and C ++ code with SWIG
Make something like Java Enum with Typescript
[Java] Make programs 10x faster with parallelStream
Execute Java code from cpp with cocos2dx
Make SpringBoot1.5 + Gradle4.4 + Java8 + Docker environment compatible with Java11
Static code analysis with Checkstyle in Java + Gradle
[Java] Explanation of Strategy pattern (with sample code)
Make Java Stream line breaks nice with eclipse
Using Gradle with VS Code, build Java → run
Easy to make LINE BOT with Java Servlet
Try debugging a Java program with VS Code
Build a Java development environment with VS Code
Script Java code
Java code TIPS
Java sample code 02
Java sample code 03
Java sample code 04
Java sample code 01
Java character code
Build Java development environment with VS Code on Mac
Getting started with Java programs using Visual Studio Code
Make Calendar gadgets made with JavaFX compatible with Java SE 9
Why can I develop Java with Visual Studio Code?
Build Java development environment with WSL2 Docker VS Code
How to build Java development environment with VS Code
[Environment construction] Build a Java development environment with VS Code!
Check coverage with Codecov in Java + Gradle + Wercker configuration
Build Java program development environment with Visual Studio Code
I used to make nc (netcat) with JAVA normally