1. Overview
In this quick tutorial, we are going to see how to generate a code coverage report for a maven project using JaCoCo.
JaCoCo is a free Java code coverage library distributed under the Eclipse Public License.
2. Version check
This tutorial has been tested with the following tools :
- Java 8
- Maven 3.8.6
- Junit 5.9.2
- Maven Surefire Plugin 2.22.0
- JaCoCo Plugin for Maven 0.8.7
3. Sample Code
To generate a coverage report we need some code to work with.
3.1. Simple calculator Class
The code we are going to use in this tutorial is a simple Java class that performs basic mathematical operations. Here is the snippet of the class :
//Simple calculator to perform basic mathematical operations
public class Calculator {
public double calculate(double firstOperand, double secondOperand, char operator){
switch (operator){
case '+':{
return add(firstOperand,secondOperand);
}
case '-':{
return subtract(firstOperand,secondOperand);
}
case '*':{
return multiply(firstOperand,secondOperand);
}
case ':':{
return divide(firstOperand,secondOperand);
}
default:
throw new IllegalArgumentException("Unsupported operation :"+operator);
}
}
private double divide(double firstOperand, double secondOperand) {
if(secondOperand == 0)
throw new IllegalArgumentException("Second argument must not be zero!");
return firstOperand / secondOperand;
}
private double multiply(double firstOperator, double secondOperand) {
return firstOperator * secondOperand;
}
private double subtract(double firstOperand, double secondOperand) {
return firstOperand - secondOperand;
}
private double add(double firstOperand, double secondOperand) {
return firstOperand + secondOperand;
}
}
3.2. Simple calculator Test Class
Below is the test class associated with the Calculator class. We have just provided a few test cases, so we can highlight the parts of our code that are covered by tests and the parts that are not.
//Junit test class for Simple calculator
public class CalculatorTest {
private static Calculator calculator;
@BeforeAll
static void setUp(){
calculator = new Calculator();
}
@Test
void addSimple(){
double result = calculator.calculate(1,1,'+');
Assertions.assertEquals(2,result);
}
@Test
void multiplySimple(){
double result = calculator.calculate(1,1,'*');
Assertions.assertEquals(1,result);
}
@Test
void subtractSimple(){
double result = calculator.calculate(1,1,'-');
Assertions.assertEquals(0,result);
}
@Test
void divideSimple(){
double result = calculator.calculate(1,1,':');
Assertions.assertEquals(1,result);
}
}
4. Adding JaCoCo Plugin to Maven
To be able to run the code coverage within a maven project, you need to add the JaCoCo maven plugin in the build section of your pom.xml, inside the plugins tag, as shown below.
--Adding jacoco plugin in pom.xml
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<!-- attached to Maven test phase -->
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
--other plugings
</plugins>
Please, note that to execute your unit tests via Maven, you need to declare the surefire plugin in your pom.xml as well. If this is not already the case, add the following line in the build section of your pom.xml, inside the plugins tag.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
5. Generating the coverage
5.1. Running the test
Run the following command from the root directory of your project to generate the code coverage of your project.
foo@bar:~$ mvn clean test
Running the previous command will trigger the JaCoCo agent and generate the coverage report in a binary format under target/jacoco.exec.
You can view the file more fashionably with a tool like SonarQube.
Fortunately, with the help of the report goal of JaCoCo Maven Plugin, we can view the coverage report directly in HTML format.
5.2. Viewing the result
Open the following file to see the results directly in a browser : target/site/jacoco/index.html
From here, you may click on the package name to have the detailed coverage per class.
Below is the legend to better understand this image :
- Green: a test covers the line of code
- Red: no test covers the line of code
- Yellow: a test partially covers the code
5.3. Adding more tests
Let’s add a few more test cases to achieve 100% coverage. Add the following test cases in the CalculatorTest class:
public class CalculatorTest {
//.....
@Test
void illegalArgument() {
Assertions.assertThrows(IllegalArgumentException.class, () -> calculator.calculate(1, 1, '/'));
}
@Test
void divideByZero() {
Assertions.assertThrows(IllegalArgumentException.class, () -> calculator.calculate(1, 0, ':'));
}
}
Now, run mvn clean test again and you should see this :
As you can see, every single line of code is now covered by tests.
6. Conclusion
In this quick tutorial, we learned how to make use of the JaCoCo maven plugin to generate code coverage reports for Java projects. For more in-depth use of JaCoCo, refer to the official documentation available here.
You can find the complete code of this article here in GitHub