Inertia

implement custom jacoco filter

Jacoco is popular coverage tool for Java worlds. It provides various options to include or exclude specific classes.

My special requirement is to generate exact coverage report for public functions of non UI classes. Jacoco doesn’t support that functionality. so I want to share my experiences here because I couldn’t find any solution for this.

The first thing I found was filters. If I can implement my own filter, then that’s all I need. Let’s analyze it more in source code level. After some time, I’ve found Filter class! It has all required filters for proper coverage reporting.

Next is implementing my own filter. Let’s reference already existing source code like AnnotationGeneratedFilter.java. Its main functionality is excludding functions annotated by having ‘Generated’ string.

I forked jacoco project and created _customFilter branch based on 0.8.3 tag and implemented WhiteListFilter and its testcase.

And I created binary using the following commands. jar files are located in jacoco/target/ folder.

mvn clean package -DskipTests=True

last thing you have to do is let gradle use those built jar files. copy those jar files to <root>/lib directory. and change your build.gradle file like the followings.

1
2
3
4
5
6
7
8
9
10
11
12
13

dependencies {
// override jacoco jars
jacocoAgent files("$rootProject.projectDir/lib/org.jacoco.agent-0.8.3.201904130250.jar")
jacocoAnt files("$rootProject.projectDir/lib/org.jacoco.ant-0.8.3.201904130250.jar",
"$rootProject.projectDir/lib/org.jacoco.core-0.8.3.201904130250.jar",
"$rootProject.projectDir/lib/org.jacoco.report-0.8.3.201904130250.jar",
"$rootProject.projectDir/lib/asm-7.0.jar",
"$rootProject.projectDir/lib/asm-tree-7.0.jar",
"$rootProject.projectDir/lib/asm-commons-7.0.jar"
)

}

then last thing you have to is annotate your target class using @TestRequired class.

1
2
3
4
5
6
7
8
9
10
@TestRequired
class MyClass {
public doSomething(String str) {
// this function will be included in coverage report.
}

private doSomethingElse(String str) {
// this function will NOT be included in coverage report.
}
}