Enforcing code coverage rule with JaCoCo in Maven lifecycle

Ayush Vardhan
3 min readMar 25, 2020

--

Automation is getting into the core of everything we do nowadays. Many of us use automation build tools like maven, gradle etc. to generate builds, check for code quality, mutation tests, deploy the builds, generate coverage reports and many more.

I believe many of us know what JaCoCo is? But just an overview, JaCoCo is a lightweight library that provides code coverage analysis in Java VM based environments. In one of my project, i used JaCoCo to generate code coverage report that provides an html page to display the analysis when build is created, and many of us do the same.

JaCoCo Report [ courtesy : https://www.eclemma.org/jacoco/trunk/coverage/index.html ]

But hardly sometime we open this html page to check the analysis. Many are dependent on sonarcube or other tools integrated with pipeline. So, lets discuss more about JaCoCo and enforce rules based on which, we will be in creating our builds.

Sample pom.xml to generate JaCoCo report:

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>generate-code-coverage-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>

Lets update above pom.xml to enforce minimum code coverage. As of now lets remove “report generation goal”.

Updated pom.xml:

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>CLASS</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
<limit>
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
<excludes>
<exclude>com.abc.ClassName</exclude>
</excludes>
</rule>
</rules>
</configuration>
</execution>

</executions>
</plugin>

Now lets understand the execution goal : ‘check’ of JaCoCo plugin. jacoco:check goal verifies that the code coverage metrics are being met. It accepts two required parameters in configuration ie. rules and HaltOnFailure. It allows some optional parameters as well like includes, excludes, skip.

HaltOnFailure expects a boolean value that behaves accordingly and halt the build if any check fails on setting true i.e the default value. Rules expect a list of rule with element type and list of limits.

Possible element types are: PACKAGE, BUNDLE, CLASS, SOURCEFILE or METHOD. Each limit is applicable for certain counters like : INSTRUCTION, BRANCH, LINE, COMPLEXITY, METHOD, CLASS and defines a min or max for corresponding values : TOTALCOUNT, COVEREDCOUNT, MISSEDCOUNT, COVEREDRATIO and MISSEDRATIO. If a limit refers to a ratio it must be in the range from 0.0 to 1.0 where the number of decimal places will also determine the precision in error messages. A limit ratio may optionally be declared as a percentage where 0.80 and 80% are same.

BUNDLE : A set of classes/packages under analysis.

Understanding the Coverage counters:

INSTRUCTION : The smallest unit JaCoCo counts are single Java byte code instructions. Instruction coverage provides information about the amount of code that has been executed or missed.

BRANCH : JaCoCo calculates branch coverage for all if and switch statements. This metric counts the total number of such branches in a method and determines the number of executed or missed branches.

LINE : For all class files that have been compiled with debug information, coverage information for individual lines can be calculated. A source line is considered executed when at least one instruction that is assigned to this line has been executed.

COMPLEXITY : JaCoCo also calculates cyclomatic complexity for each non-abstract method and summarizes complexity for classes, packages and groups. Cyclomatic complexity is the minimum number of paths that can, in (linear) combination, generate all possible paths through a method.

METHOD : Each non-abstract method contains at least one instruction. A method is considered as executed when at least one instruction has been executed.

CLASS : A class is considered as executed when at least one of its methods has been executed. Note that JaCoCo considers constructors as well as static initializers as methods.

So, with this ample parameters, JaCoCo provides the ability to match our quality standards very easily at an early stage.

Now with the updated pom.xml, when we try to create a build using “mvn clean install”, if specified metrics are matched then build generation process will be successful otherwise it fails with error trace messages.

Well, that’s all from my end on this. Always open for feedback. Hope this sharing helps.

Thank you!

courtesy : https://www.eclemma.org/jacoco/trunk/index.html

--

--

Ayush Vardhan
0 Followers

SDE @dbsbank India. Algorithm lover, Mainframe guy, Data Science enthusiast :)