clover-instr

Still need help?

The Atlassian Community is here for you.

Ask the community

Description

The <clover-instr> task produces instrumented versions of sets of Java source files. These can then be compiled in place of the original source to produce an instrumented Java build.

The <clover-instr> task is provided for users who can't make use of the standard <clover-setup> integration task. The <clover-setup> task offers a simpler and less intrusive integration option for most users.

Be aware that this element does not support Groovy code.

The basic nesting of elements within the <clover-instr> task is as follows:

<clover-instr>
    <distributedCoverage/>
    <fileset/>
    <methodcontext/>
    <statementcontext/>
    <profiles/>
    <testsources>
        <testclass>
            <testmethod/>
        </testclass>
    </testsources>
</clover-instr>

Parameters

Attribute

Description

Required

destdir

The directory into which Clover will write an instrumented copy of the source code.

Yes.

initstring

The Clover initString describes the location of the Clover coverage database. Typically this is a relative or absolute file reference, e.g. ${basedir}/build/clover.db. If not specified it defaults to .clover, relative to the project's base directory.

No.

flushinterval

When the flushpolicy is set to interval or threaded this value is the minimum period between flush operations (in milliseconds).

No.

flushpolicy

This attribute controls how Clover flushes coverage data during a test run. Valid values are directed, interval or threaded.

directed — Coverage data is flushed at JVM shutdown, and after an inline flush directive.

interval — Coverage data is flushed as for directed, as well as periodically at a maximum rate based on the value of flushinterval. This is a 'passive' mode in that flushing potentially occurs as long as instrumented code is being executed.

threaded — Coverage data is flushed as for directed, as well as periodically at a rate based on the value of flushinterval. This is an 'active' mode in that flushing occurs on a separate thread and is not dependent on the execution of instrumented code.

For more information, see Using a Flush Policy.

No; defaults to directed.

fullyQualifyJavaLang

This should only be set to 'false' if you have defined a variable called 'java' in your source files. If false, Clover will instrument source files without using fully qualified java.lang names.

No; defaults to 'true'.

instrumentationLevel

This setting can reduce accuracy to method level, to enhance the speed of instrumentation, compilation & test execution. Valid values are 'method' and 'statement'.

No; defaults to statement.

instrumentLambda

Since 3.2.2. Whether Java 8 lambda functions shall be instrumented. If instrumented, they're treated like normal methods (and can be shown in HTML report and considered in code metrics, for example). Possible values:

  • none - do not instrument lambda functions,
  • expression - instrument lambdas in expression-like form, e.g. "(a, b) -> a + b",
  • block - instrument lambdas in code blocks, e.g. "(a, b) -> { return a + b; }"
  • all - instrument all lambda functions.

(warning) Due to Clover's restrictions related with code instrumentation and javac compiler's type inference capabilities, you may get compilation errors when expression-like lambda functions are passed to generic methods or types. In such case disable instrumentation of expression-like form (i.e. use the none or block setting). See the Java 8 code instrumented by Clover fails to compile Knowledge Base article for more details.

No; defaults to "all" in 3.2.2-4.0.2 and to "none" since 4.0.3.

recordTestResults

If set to 'false', test results will not be recorded; instead, results can be added via the <testResults> fileset at report time. For more details please see 'Advanced Usage'.

No; defaults to 'true'. 

relative

This controls whether the initstring parameter is treated as a relative path or not.

No; defaults to 'false'.

srcdir

The directory of source code to instrument.

Yes, unless a nested clover-instr element is used.

source

The source level to process source files at. It is recommended that you set this parameter, either here or on <javac> invocations.

No; defaults to the Java version detected at runtime.

Nested Elements of <clover-instr>

<distributedCoverage>

This element turns on Clover's distributed coverage feature, enabling the collection of per-test coverage data, when your test environment requires more than one JVM (Java Virtual Machine).

Parameters

Attribute name

Description

Required

name

The name of this configuration.

No; defaults to 'tcp-config'

port

The port the test JVM should listen on.

No; defaults to '1198'

host

The hostname the test JVM should bind to.

No; defaults to 'localhost'

timeout

(a number) The amount of time (in milliseconds) to wait before a connection attempt will fail.

No; defaults to '5000'

numClients

(a number) The number of clients that need to connect to the test server before the tests will continue.

No; defaults to '0'

retryPeriod

(a number) The amount of time (in milliseconds) to wait before attempting to reconnect in the event of a network failure.

No; defaults to '1000'

(info) All attributes are optional.

 

<fileset>

Specifies a set of source files to instrument.

 

<methodContext>

Specifies a method Context definition. See Using Coverage Contexts for more information.

Parameters

Attribute

Description

Required

name

The name for this context. Must be unique, and not be one of the reserved context names (see Using Coverage Contexts).

Yes.

regexp

A Perl 5 Regexp that defines the context. This regexp should match the method signatures of methods you wish to include in this context. Note that when method signatures are tested against this regexp, whitespace is normalized and comments are ignored.

Yes.

maxComplexityMatch a method to this pattern if its cyclomatic complexity is not greater than maxComplexity. In other words - all methods with complexity <= maxComplexity will be filtered out.No.
maxStatementsMatch a method to this pattern if its number of statements is not greater than maxStatements. In other words - all methods with statements <= maxStaments will be filtered out.No.
maxAggregatedComplexitySince 3.1.10. Match a method to this pattern if its aggregated cyclomatic complexity is not greater than maxAggregatedComplexity. In other words - all methods with aggregated complexity <= maxAggregatedComplexity will be filtered out. Aggregated complexity metric is a sum of the method complexity and complexity of all anonymous inline classes declared in the method.No.
maxAggregatedStatementsSince 3.1.10. Match a method to this pattern if its number of aggregated statements is not greater than maxAggregatedStatements. In other words - all methods with aggregated statements <= maxAggregatedStaments will be filtered out. Aggregated statements metric is a sum of the method statements and statements of all anonymous inline classes declared in the method.No.

 

What is the difference between maxComplexity and maxAggregatedComplexity or maxStatements and maxAggregatedStatements?

Aggregated metrics calculate method statements/complexity including the code of all anonymous inline classes declared inside the method. Thanks to this, it is possible to distinguish between a trivial single-statement method like:

int getNumber() {
   return number;
}

and a single-statement method which actually returns more complex data, like:

ActionListener getListener() {
   return new ActionListener() {
       public void actionPerformed(ActionEvent e) {
           System.out.println("statement #1");
           System.out.println("statement #2");
           System.out.println("statement #3");
       }
   };
}

 

If you would use a method context filter with maxStatements attribute, like the following:

<methodContext name="trivial" regexp=".*" maxStatements="1">

then both getNumber() and getListener() methods would be filtered-out, because each of them contains only one statement: "return <xxx>".

 

If you would use new maxAggregatedStatements, for instance:

<methodContext name="trivial" regexp=".*" maxAggregatedStatements="1">

then the getNumber() would be filtered-out and the getListener() method would not be filtered out (because it contains 4 statements in total - 1 "return" statement from the method itself and 3 "System.out.println()" statements from anonymous class).

 

Regular expression tip:

(lightbulb) If you would like to filter-out all methods, except those having a specific name, you could write a negative-look-ahead regular expression. For example:

<methodContext name="trivial" regexp="^(?!.*(getRunnable|getListener)).*$" maxStatements="1"/>

will filter-out all methods having not more than one statement, except those which are named getRunnable or getListener.

 

 

<statementContext>

Specifies a statement Context definition. See Using Coverage Contexts for more information.

This element does not support Groovy.

Parameters

Attribute

Description

Required

name

The name for this context. Must be unique, and not be one of the reserved context names (see Using Coverage Contexts).

Yes.

regexp

A Perl 5 Regexp that defines the context. This regexp should match statements you wish to include in this context. Note that when statements are tested against this regexp, whitespace is normalized and comments are ignored.

Yes.

 

<profiles>

Since 3.1.11. Optional element. Defines a list of Clover profiles, which can be selected at runtime by providing a clover.profile=<name> system property. Thanks to this you can change some of Clover's behavior without code recompilation.

<profiles>
  <profile name="default" coverageRecorder="FIXED|GROWABLE|SHARED">
    <distributedCoverage/> <!-- optional -->
  </profile>
  <profile .../>
  <!-- more profiles -->
</profile>

 

<profile>

Since 3.1.11. Contains a definition of a single runtime profile.

Parameters

Attribute

Description

Required

name

The name for this profile; name must be unique among profiles. There must be one profile named "default".

No. Defaults to "default".

coverageRecorder

Type of coverage recorder which will be used for gathering coverage data at runtime. Possible values: FIXED, GROWABLE, SHARED (case insensitive).

(warning) Warning: we strongly recommend using the default setting. Do not change until you deeply understand how it works.

No. Defaults to "FIXED".

Nested elements

<distributedCoverage/>

(lightbulb)Note: a definition in <profile>/<distributedCoverage> element has priority over the <clover-setup|clover-instr>/<distributedCoverage> element.

Selecting clover.profile at runtime

Clover profile is being selected at runtime using the following algorithm:

  • Are there any profiles defined in compiled code?
    • yes -
      • 1. read the clover.profile system property. is it defined?
        • yes - use the value as profile name
        • no - use the "default" profile name
      • 2. is the profile name found on list of defined profiles?
        • yes - use settings from this profile
        • no - use system settings (default coverage recorder etc...)
    • no - use system settings (default coverage recorder etc...)

So it fall-backs to default system settings in case of missing profile.

 

 

<testsources>

<testsources> is an Ant fileset which should only be used if Clover's default test detection is not adequate. Clover's default test detection algorithm is used to distinguish test cases if this element is omitted.

To have test sources reported in a separate tree to your application code, use the <testsources/> element in the <clover-report/> task.

Nested elements of <testsources>
<testclass>

<testclass> can be used to include only specific test classes.

Parameters

Attribute

Description

Required

name

A regex on which to match the test class's name.

No.

super

A regex on which to match the test class's superclass.

No.

annotation

A regex on which to match the test class's annotation.

No.

package

A regex on which to match the test class's package.

No.

tag

A regex on which to match the test class's javadoc tags.

No.

(info) For more information about regular expressions, please visit http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html#sum.

<and>

<and> can be used to specify multiple instances of <testclass>, all of which must be matched for a class to be detected as a test, e.g.:

<testsources dir="tests">
<and>
  <testclass annotation="Specification"/>
  <testclass annotation="Test"/>
</and>
<testsources>

In this example, a class will only be recognized as a test if it has "Specification" and "Test" annotations.

<or>

<or> can be used to specify multiple instances of <testclass>, any of which must be matched for a class to be detected as a test, e.g.:

<testsources dir="tests">
<or>
  <testclass name=".*Spec"/>
  <testclass name=".*Test"/>
</or>
<testsources>

In this example, a class will be recognized as a test if its name matches ".*Spec", or its name matches ".*Test".

Nested elements of <testclass>
<testmethod>

<testmethod> can be used to perform more fine grained detection of test methods.

(warning) Clover matches methods only; it does not match constructors (CLOV-1339).

Parameters

Attribute

Description

Required

name

A regex on which to match the test method's name.

No.

annotation

A regex on which to match the test method's annotation.

No.

tag

A regex on which to match the test method's javadoc tags.

No.

returntype

A regex on which to match the return type of the method, e.g.:

  • ".*" will match any return type.
  • "void" will match methods with no return type.

No.

Note that you can include multiple instances of <testmethod>, in which case they will be treated as 'or' clauses, e.g.:

<testsources dir="tests">
  <testclass>
    <testmethod annotation="Specification"/>
    <testmethod name="^should.*"/>
    <testmethod name="^must.*"/>
  </testclass>
<testsources>

In this example, a method will be recognized as a test if its annotation is "Specification", or its name matches "^should*", or its name matches "^must*".

Examples

<clover-instr srcdir="src" destdir="instr"/>

Produce an instrumented copy of all source files in the srcdir into the destdir. The Clover registry is at the default location.

 

<clover-instr destdir="instr"/>
     <fileset dir="src">
       <include name="**/*.java"/>
     </fileset>
</clover-instr>

This example achieves the same as the first example, but using an embedded fileset.

 

<clover-instr destdir="instr"/>
     <testSources dir="src">
         <include name="**/*Test.java"/>
         <testclass name=".*Test">
             <testmethod name=".*Bag.*"/> <!-- only the Bag related tests -->
         </testclass>
     </testSources>
</clover-instr>

This example produces an instrumented copy which recognizes all of the following as tests: classes in the directory "src"; classes in files whose names end with "Test"; methods whose names contain with "Bag".

 

Interval Flushing

By default Clover will write coverage data to disk when the hosting JVM exits, via a shutdown hook. This is not always practical, particularly when the application you are testing runs in an Application Server. In this situation, you can configure Clover to use 'interval' flushing, where coverage data is written out periodically during execution:

<clover-instr flushpolicy="interval" flushinterval="5000" srcdir="src" destdir="instr" />

The "flushinterval" defines in milliseconds the minimum interval between coverage writes.

 

Specifying the location of the Clover Database.

By default, Clover writes its internal database to the .clover directory relative to the project's basedir. To override this location, use the initstring attribute.

<clover-instr initstring="clover-db/coverage.db" srcdir="src" destdir="instr"/>

This example will use clover-db/coverage.db as the location for the Clover database. Note that the directory clover-db should exist before running this task.

 

Troubleshooting

Clover does not support parallel instrumentation

You cannot use <parallel/> task for code instrumentation, for instance:

<target name="instrument">
  <parallel>
    <clover-instr srcdir="module1" destdir="module1-instr" .../>
    <clover-instr srcdir="module2" destdir="module1-instr" .../>
  </parallel>
</target>

will produce error message like:

[clover] Error finalising instrumentation:
   [clover] java.io.IOException: Failed to move tmp registry file /myproject/.clover/clover3_1_6.db.tmp to final registry file

 

 

Last modified on May 26, 2016

Was this helpful?

Yes
No
Provide feedback about this article
Powered by Confluence and Scroll Viewport.