FilteringOptions

David Engfer edited this page Jan 23, 2017 · 32 revisions

This page discusses a not yet available feature!

The JaCoCo Analyzer should allow to hook-in filters, that filters synthetic compiler constructs or code, that should not be considered for code coverage. This page is a collection of filters that might be useful.

Filters for Synthetic Compiler Constructs

For technical reasons the Java compiler sometimes creates additional byte code, that seems to have no relation to the source code. Highlighting such code in coverage reports is confusing and therefore should be filtered out.

  • JAVAC.SYNTHCLASS - synthetic classes
  • JAVAC.SYNTHMETH - synthetic methods
  • JAVAC.CLASS - try/catch blocks for class literals
  • JAVAC.SYNC - release lock code in synchronized statements
  • JAVAC.FINALLY - finally block emitted twice
  • JAVAC.ENUM - static methods and initializer generated for enum types
  • JAVAC.ASSERT - branches created by the Java assert statement
  • JAVAC.TRYWITH - extra exception handlers installed to close resources from try/with statements
  • JAVAC.STRINGSWITCH - extra branches due to implementation with hashcode and equals comparison
  • default branch in switch on an enum type if the other cases cover all the possibile enum values
  • JAVAC.NOT - branches created by the not Operator ! on boolean values
  • SCALAC.MIXIN - methods from mixin-classes
  • SCALAC.CASE - synthetic methods from Scala case classes. Like mixin, these appear on the same line number as the constructor. [idea from @retronym]
  • GROOVYC.METHODS - methods from GroovyObject
  • GROOVYC.ANNOTATIONS - methods from AST transformations
  • LOMBOK.DATA - generated getters, setters, equals, hashcode, toString
  • KOTLIN.PROPERTIES - generated getters and setters

Filters for Code where Test Execution is Questionable or Impossible by Design

  • Private, empty default constructors - assuming no calls to it
  • Plain getters and setters
  • Blocks that throw AssertionErrors - Entire block should be ignored if a condition (if !assertion throw new AssertionError)
  • For switch statements which cover all values of a enum the default branch cannot be covered

Filters Based on Manual Tagging

Filters might parse source code to find lines with with special tags like

} catch (SomeException e) {
  dohandle(e); // $COVERAGE-IGNORE$
}

In such a case all blocks overlapping with the tagged line could be ignored.

Annotation-Based Filtering

Filtering out methods and classes based on attributes much like .NET does it.

@ExcludeFromCodeCoverage
public void someMethodThatShouldNotHaveCoverage() {
  ...
}

Filters based on excludes configuration

Agent "excludes" property should manage the '#' separator to exclude some members.

com.sample.MyEnum#valueOf(String)
com.sample.MyEnum#valueOf(*)
com.sample.MyEnum#values()

Examples

The following example creates an anonymous class Foo$1 when compiled with JDK 5.0, but does not with ECJ or JDK 6.0. Adding in the constructor also stops creation of the class.

public class Test {

private class Foo {
  /* public Foo() {} */
  public void run() {}
  }

  public void execute() {
    new Foo().run();
  }
}

Pitfalls

The access flags reported by ClassReader does not include pseudo access flags that are stored in code attributes. It seems as if the correct access flags are only reported during the visit methods of ClassVisitor. To make things more interesting, you only get the right flags for inner classes after visit inner has been called (which happens after visit and visit source).

Filters based on a SCM changeset

Filtering code coverage only for New and Modified lines on a specific branch can help to determine the coverage of a new feature before merging it on the "main/master/trunk" branch.