FilteringOptions

Evgeny Mandrikov edited this page Sep 7, 2018 · 103 revisions

This wiki is primarily used by JaCoCo developers to analyze and design new features. For users please see the latest documentation.

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 implemented in versions starting from 0.8.0 are enabled unconditionally and take place during generation of report from exec file, therefore tools that directly read exec files and embed JaCoCo for this (such as SonarQube or Jenkins) will provide filtering functionality only after they updated to this version of JaCoCo.

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.

Kotlin/Groovy/Scala/etc

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

  • :white_check_mark: Private empty constructors that do not have arguments - Done in 0.8.0
  • @originalcvk: Empty (non-constructor) methods, whether called or not
  • 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
    • Godin: wouldn't this require an analysis of an enum class file, which might be unavailable at analysis time?

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.

No, citing a comment that explains why:

The agent always instruments all methods. Whether a method is included in the coverage report is a plain decision at analysis time. If we would adjust instrumentation in addition, we would need to always configure both places (agent and analysis) always the exact way. Note: Exec files do not come with any meta information about the probes. Probes are derived from the structure of the class file only. Therefore this process must create the same results at instrumentation and analysis time.

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();
  }
}

Godin: what this example demonstrates? To me seems that generated class has no executable lines and also comment is incorrect - name of class is Test$1 and it is generated by all versions of JDK.

===

Constructor of anonymous classes when compiled with ECJ 3.12.3 contains reference to a first line of source code:

package org.example;
class Fun {
  void fun() {
    new Object() {
    };
  }
}

Seems that this was fixed in ECJ 3.14.0

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.

Testing

Testing that filtering doesn't cause analysis failures can be done using Command Line Interface:

find ~/.m2 -type f -name "*.jar" -exec \
    java -jar jacococli.jar report --quiet --classfiles {} \; 
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.