72

I have some code in Java that I want to exclude from code coverage. How would I do this? I want to be able to add an annotation. Is there a way to configure or extend jacoco (as used in gradle) to use this?

Example:

public class Something
{
    @ExcludeFromCodeCoverage
    public void someMethod() {}
}
Kamal Chandraprakash
  • 1,872
  • 18
  • 28
Don Rhummy
  • 24,730
  • 42
  • 175
  • 330

6 Answers6

61

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() {}
}
Mohamed Anees A
  • 4,119
  • 1
  • 22
  • 35
24

The new feature has been added in the 0.8.2 release of JaCoCo which filters out the classes and methods annotated with @Generated. For details please see the documentation below:

Classes and methods annotated with annotation whose retention policy is runtime or class and whose simple name is Generated are filtered out during generation of report (GitHub #731).

JaCoCo 0.8.2 Release Notes

Ajinkya
  • 544
  • 4
  • 9
9

Tl;dr

Use annotation @lombok.Generated from Lombok.

Explanation

Jacoco integrates with Lombok. Code generated by Lombok is excluded from Jacoco coverage by default (see Release 0.8.0 in Jacoco changelog). You can misuse lombok.Generated at your method for it being excluded from the coverage report.

Markus Schulte
  • 4,171
  • 3
  • 47
  • 58
  • 3
    Lombok uses undocumented, unofficial classes that are not guaranteed to be in every java runtime. (And that are strongly recommended not to be used) – Don Rhummy May 28 '19 at 13:44
  • Very important to note that this is a hack workaround. Highly suggest avoiding. – Mike Feb 03 '20 at 20:55
  • How would one "extend" the `@Generated` annotation to be able to rename it to something like OP suggested: `@ExcludeFromCodeCoverage` ? – payne Apr 22 '20 at 19:17
  • I am pretty sure you would have to patch JaCoCo for doing so. – Markus Schulte Apr 23 '20 at 07:08
8

I have some code in Java that I want to exclude from code coverage. How would I do this? I want to be able to add an annotation. Is there a way to configure or extend jacoco (as used in gradle) to use this?

As of today there is no such feature in latest released version of JaCoCo (0.7.9). Only whole classes can be excluded.

On page https://github.com/jacoco/jacoco/wiki/FilteringOptions#annotation-based-filtering (which is dedicated for developers) this is recorded as an idea for future versions.

Official JaCoCo documentation contains information about how to obtain latest unreleased build as well as list of unreleased changes for next version - http://www.jacoco.org/jacoco/trunk/doc/changes.html , which includes various filters, among which filtering of methods that are generated by Lombok and Groovy and marked by annotations lombok.Generated and groovy.transform.Generated respectively. Potentially you can abuse this, but I wouldn't recommend to do so for many various reasons.

Godin
  • 9,801
  • 2
  • 39
  • 76
  • 1
    +1, but... what would be a legitimate use for such an annotation? I can't find any such example anywhere, and my feeling is that this feature in a coverage tool would only get misused and abused. If a method exists in source code and is not empty, then I think it *should* be accounted for in coverage analysis, even if the source code was generated by some tool. After all, the method supposedly would give *some* contribution to the app/system functionality, right? If so, why not test it? – Rogério Jan 07 '18 at 18:50
  • 1
    @Rogério - private constructors in "static" helper classes - I don't think using reflection to force the constructor execution is the right approach... – CptBartender Jan 30 '18 at 15:51
  • @CptBartender Of course calling the private constructor through Reflection is not the solution... The proper solution is for the code coverage tool to automatically filter them out; JaCoCo is already doing it for a private empty constructor. – Rogério Jan 30 '18 at 16:03
  • 4
    @Rogério I'd like to not cover main() methods that are used for Q&D testing or examples of how to use the class. That naively seems like a legit use case. – elhefe May 03 '18 at 02:03
  • @elhefe Such code (`main` methods for testing, examples) is best put in their own source files, to avoid polluting the production codebase. And coverage tools already support the exclusion of selected source files or classes. – Rogério May 04 '18 at 18:35
  • I'd say, code that exists purely for GUI initialization. Or maybe I just don't know how to test it – CLOVIS Mar 02 '19 at 14:46
  • 1
    Is latest version of JaCoCo support this feature? – Manju Nov 13 '19 at 11:26
  • I'd omit toString methods but these can be generated by Lombok. – Linus Fernandes Jun 22 '20 at 09:55
8

Following @mohamed-anees-a approach, I got to this kotlin version:

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class ExcludeFromJacocoGeneratedReport
Silas Pedrosa
  • 196
  • 1
  • 4
6

You can set lombok.addLombokGeneratedAnnotation = true into lombok.config in the root of project. After that, all Lombok-generated code will be ignored by Jacoco.

See more in Project Lombok documentation: https://projectlombok.org/features/configuration

genius
  • 71
  • 1
  • 3
  • Lombok uses undocumented, unofficial classes that are not guaranteed to be in every java runtime. (And that are strongly recommended not to be used) – Don Rhummy Jun 15 '20 at 13:57
  • @DonRhummy I don't know if I understand your comment correctly, Lombok, is a compile time dependency/plugin and applications will be shipped with compiled code which should not include anything related to lombok. Please, let me know if I am missing something. – Andrews Apr 18 '21 at 03:20
  • Note that the question is not about Lombok, so this wouldn’t work for the general case. The feature you mention _is_ documented but it simply does not help here – hence, I think, the confusing comment by @DonRhummy (copied from another answer where it really applies). – Didier L Nov 21 '22 at 10:48