Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Introduction

In this tutorial, we’ll learn how to exclude certain classes and packages from JaCoCo test coverage reports.

Generally, the candidates for exclusion can be configuration classes, POJOs, DTOs, as well as generated byte code. These carry no specific business logic, and it could be useful to exclude them from the reports in order to provide a better view of the test coverage.

We’ll explore various ways of exclusion in both Maven and a Gradle project.

2. Example

Let’s start with a sample project where we have all the required code already covered by tests.

Next, we’ll generate the coverage report by running mvn clean package or mvn jacoco:report:

Screenshot-2021-05-30-at-21.07.46

This report shows that we already have the required coverage, and missed instructions should be excluded from JaCoCo report metrics.

3. Excluding Using Plugin Configuration

Classes and packages can be excluded using standard * and ? wildcard syntax in the plugin configuration:

  • * matches zero or more characters
  • ** matches zero or more directories
  • ? matches a single character

3.1. Maven Configuration

Let’s update the Maven plugin to add several excluded patterns:

<plugin> 
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <configuration>
        <excludes>
            <exclude>com/baeldung/**/ExcludedPOJO.class</exclude>
            <exclude>com/baeldung/**/*DTO.*</exclude>
            <exclude>**/config/*</exclude>
        </excludes>
     </configuration>
     ...
</plugin>

Here we’ve specified the following exclusions:

  • ExcludedPOJO class in any sub-package under com.baeldung package
  • all classes with names ending in DTO in any sub-package under com.baeldung package
  • the config package declared anywhere in the root or sub-packages

3.2. Gradle Configuration

We can also apply the same exclusions in a Gradle project.

First, we’ll update the JaCoCo configuration in build.gradle and specify a list of exclusion, using the same patterns as earlier:

jacocoTestReport {
    dependsOn test // tests are required to run before generating the report
    
    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it, exclude: [
                "com/baeldung/**/ExcludedPOJO.class",
                "com/baeldung/**/*DTO.*",
                "**/config/*"
            ])
        }))
    }
}

We use a closure to traverse the class directories and eliminate files that match a list of specified patterns. As a result, generating the report using ./gradlew jacocoTestReport or ./gradlew clean test will exclude all the specified classes and packages, as expected.

It’s worth noting that the JaCoCo plugin is bound to the test phase here, which runs all the tests prior to generating the reports.

4. Excluding With Custom Annotation

Starting from JaCoCo 0.8.2, we can exclude classes and methods by annotating them with a custom annotation with the following properties:

  • The name of the annotation should include Generated.
  • The retention policy of annotation should be runtime or class.

First, we’ll create our annotation:

@Documented
@Retention(RUNTIME)
@Target({TYPE, METHOD, CONSTRUCTOR})
public @interface Generated {
}

Now we can annotate class(es) or method(s) or constructor(s) that should be excluded from the coverage report.

Let’s use this annotation at the class level first:

@Generated
public class Customer {
    // everything in this class will be excluded from jacoco report because of @Generated
}

Similarly, we can apply this custom annotation to a specific method in a class:

public class CustomerService {

    @Generated
    public String getProductId() {
        // method excluded form coverage report
    }
    
    public String getCustomerName() {
        // method included in test coverage report
    }
}

Finally, let’s apply the annotation to the constructor:

public class CustomerService {
    
    @Generated
    public CustomerService(){
        //constructor excluded from coverage report
    }

}

5. Excluding Lombok Generated Code

Project Lombok is a popular library for greatly reducing boilerplate and repetitive code in Java projects.

Let’s see how to exclude all Lombok-generated bytecode by adding a property to lombok.config file in our project’s root directory:

lombok.addLombokGeneratedAnnotation = true

Basically, this property adds the lombok.@Generated annotation to the relevant methods, classes, and fields of all the classes annotated with Lombok annotations, e.g. the Product class. As a result, JaCoCo then ignores all the constructs annotated with this annotation, and they’re not shown in the reports.

Finally, we can see the report after applying all the exclusion techniques shown above:

Screenshot-2021-05-30-at-21.25.03

6. Conclusion

In this article, we demonstrated various ways of specifying exclusions from the JaCoCo test report.

Initially, we excluded several files and packages using naming patterns in the plugin configuration. Then we saw how to use @Generated to exclude certain classes, as well as methods. Finally, we learned how to exclude all the Lombok-generated code from the test coverage report using a config file.

As always, the Maven source code and Gradle source code are available over on Github.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.