How to Exclude Classes from Test Coverage Using Java Annotations in Spring Boot

Is there an easy way to exclude classes from test coverage using Java Annotations in Spring Boot?

This is what ended up working for me. Had to write some custom custom filtering logic in a very hacky sort of way, but it did the job.

Upvoting @Min Hyoung Hong's answer for leading me down the right track.

build.gradle.kts

tasks {
withType<KotlinCompile<KotlinJvmOptions>> {
kotlinOptions.freeCompilerArgs = listOf("-Xjsr305=strict")
kotlinOptions.jvmTarget = "1.8"
}

withType<JacocoReport> {
reports {
xml.isEnabled = false
csv.isEnabled = false
html.destination = file("$buildDir/jacocoHtml")
}

afterEvaluate {
val filesToAvoidForCoverage = listOf(
"/dto",
"/config",
"MyApplicationKt.class"
)
val filesToCover = mutableListOf<String>()
File("build/classes/kotlin/main/app/example/core/")
.walkTopDown()
.mapNotNull { file ->
var match = false
filesToAvoidForCoverage.forEach {
if (file.absolutePath.contains(it)) {
match = true
}
}
return@mapNotNull if (!match) {
file.absolutePath
} else {
null
}
}
.filter { it.contains(".class") }
.toCollection(filesToCover)

classDirectories = files(filesToCover)
}
}
}

How would I add an annotation to exclude a method from a jacoco code coverage report?

Since there are no direct answers to this, did a bit of research and came across this PR.

https://github.com/jacoco/jacoco/pull/822/files

  private static boolean matches(final String annotation) {
final String name = annotation
.substring(Math.max(annotation.lastIndexOf('/'),
annotation.lastIndexOf('$')) + 1);
return name.contains("Generated")
}

You can create any annotation with name containing "Generated". I've created the following in my codebase to exclude methods from being included in Jacoco report.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExcludeFromJacocoGeneratedReport {}

Use this annotation in your methods to exempt it from coverage as below.

public class Something
{
@ExcludeFromJacocoGeneratedReport
public void someMethod() {}
}

Maven Jacoco Configuration - Exclude classes/packages from report not working

Your XML is slightly wrong, you need to add any class exclusions within an excludes parent field, so your above configuration should look like the following as per the Jacoco docs

<configuration>
<excludes>
<exclude>**/*Config.*</exclude>
<exclude>**/*Dev.*</exclude>
</excludes>
</configuration>

The values of the exclude fields should be class paths (not package names) of the compiled classes relative to the directory target/classes/ using the standard wildcard syntax

*   Match zero or more characters
** Match zero or more directories
? Match a single character

You may also exclude a package and all of its children/subpackages this way:

<exclude>some/package/**/*</exclude>

This will exclude every class in some.package, as well as any children. For example, some.package.child wouldn't be included in the reports either.

I have tested and my report goal reports on a reduced number of classes using the above.

If you are then pushing this report into Sonar, you will then need to tell Sonar to exclude these classes in the display which can be done in the Sonar settings

Settings > General Settings > Exclusions > Code Coverage

Sonar Docs explains it a bit more

Running your command above

mvn clean verify

Will show the classes have been excluded

No exclusions

[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:report (post-test) @ ** ---
[INFO] Analyzed bundle '**' with 37 classes

With exclusions

[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:report (post-test) @ ** ---
[INFO] Analyzed bundle '**' with 34 classes

Hope this helps

Globally exclude all Spring JavaConfig from Clover code coverage

At the moment Clover allows to exclude code from coverage measurement using five methods:

  1. excluding entire file

    • in Ant it is <clover-setup> / <fileset> / <excludes> tag
    • in Maven it is <excludes>, <excludesFile> or <excludesList> option
  2. excluding certain methods

    • in Ant it is <clover-setup> / <methodContext> tag combined with the <clover-report> / <current> / <
    • in Maven it is not available directly - you'd have to use the <reportDescriptor> option to configure report format in an external XML file; the problem is with clover-setup which you'd also have to customise - maybe calling the Clover via maven-antrun-plugin could help here
  3. excluding certain statements

    • in Ant it is <clover-setup> / <statementContext> tag combined with the <clover-report> / <current> / <
    • in Maven you'd have to use the <reportDescriptor>
  4. excluding certain code blocks

    • in Ant it is <clover-report> / <current> / < with a predefined names of blocks, e.g. 'constructor' or 'switch' - see Using+Coverage+Contexts for more details
    • in Maven you'd have to use the <reportDescriptor>
  5. excluding arbitrary source lines

You can put //CLOVER:OFF and //CLOVER:ON inline comments in the source code

Unfortunately, at the moment it's not possible to exclude the given class. However, I can see few workarounds available:

  1. Add the //CLOVER:OFF and //CLOVER:ON comments around classes you want to exclude.

  2. Exclude entire files

  3. Treat these @Configuration classes as test code.

This is a hack. Clover allows to declare which classes are test classes. The match is based on file name, class signature and test signature. See the <clover-setup> / <testsources> / <testclass> tag. In this testclass tag you can define a regular expression matching entire class signature. In your case it could be:

<testclass annotation=".*@Configuration.*"/>

While this will not disable code instrumentation for these classes, they would be treated as test code and they should not contribute to application code metrics.

Note that Clover calculates code metrics for application and test code separately.

References:

  • https://docs.atlassian.com/clover-maven-plugin/latest/clover-setup.html
  • https://docs.atlassian.com/clover-maven-plugin/latest/clover-mojo.html
  • https://confluence.atlassian.com/display/CLOVER/Creating+custom+reports
  • https://confluence.atlassian.com/display/CLOVER/Using+Coverage+Contexts

How to exclude classes from the coverage calculation in EclEmma without actually excluding them from the coverage itself

For technical reasons it might be necessary to exclude certain classes from code coverage analysis. The following options configure the coverage agent to exclude certain classes from analysis. Except for performance optimization or technical corner cases these options are normally not required.

  1. Excludes: A list of class names that should be excluded from
    execution analysis. The list entries are separated by a colon (:)
    and may use wildcard characters (* and ?). (Default: empty)

  2. Exclude classloaders: A list of class loader names that should be
    excluded from execution analysis. The list entries are separated by
    a colon (:) and may use wildcard characters (* and ?). This option
    might be required in case of special frameworks that conflict with
    JaCoCo code instrumentation, in particular class loaders that do not
    have access to the Java runtime classes. (Default:
    sun.reflect.DelegatingClassLoader)

Warning: Use these options with caution! Invalid entries might break
the code coverage launcher. Also do not use these options to define
the scope of your analysis. Excluded classes will still show as not
covered.

Resource Link:

  1. EclEmma Code Coverage Preferences

The following examples all specify the same set of inclusion/exclusion patterns:

  1. <filter includes="com.foo.*" excludes="com.foo.test.*,
    com.foo.*Test*" />
  2. <filter includes="com.foo.*" /> <filter excludes="com.foo.test.*,
    com.foo.*Test*" />
  3. <filter value="+com.foo.*, -com.foo.test.*, -com.foo.*Test*" />

    <filter excludes="com.foo.*Test*" file="myfilters.txt" />

    where myfilters.txt file contains these lines:

    -com.foo.test.*
    +com.foo.*

Resource Link:

  1. Coverage filters
  2. I am certain that all of my classes are built with -g(debug='true')
    and yet EMMA still complains about missing debug info!

Ignore code coverage for unit tests in EclEmma

Preferences->Java->Code Coverage and set the "Only path entries matching" option to src/main/java - seems to work nicely

Exclude methods from code coverage with Cobertura

You can exclude classes from instrumentation. Then they should not appear on reports. See exclude statements below.

You can also ignore calls to some methods. See ignore statement below.

If you are using maven, see maven plugin manual.

    <configuration>
<instrumentation>
<ignores>
<ignore>com.example.boringcode.*</ignore>
</ignores>
<excludes>
<exclude>com/example/dullcode/**/*.class</exclude>
<exclude>com/example/**/*Test.class</exclude>
</excludes>
</instrumentation>
</configuration>

And for ant see this.

<cobertura-instrument todir="${instrumented.dir}">
<ignore regex="org.apache.log4j.*" />
<fileset dir="${classes.dir}">
<include name="**/*.class" />
<exclude name="**/*Test.class" />
</fileset>
<fileset dir="${jars.dir}">
<include name="my-simple-plugin.jar" />
</fileset>
</cobertura-instrument>


Related Topics



Leave a reply



Submit