Index
User Guide
FAQ


Clover Website



 

Frequently Asked Questions

Code Coverage Analysis

What is Code Coverage Analysis?
Code Coverage Analysis is the process of discovering code within a program that is not being exercised by test cases. This information can then be used to improve the test suite, either by adding tests or modifying existing tests to increase coverage.
Code Coverage Analysis shines a light on the quality of your unit testing. It enables developers to quickly and easily improve the quality of their unit tests, which ultimately leads to improved quality of the software under development.
A good introduction to the various types of Code Coverage Analysis can be found here.

Where did Clover come from?
Clover was originally developed at Cortex as an internal tool to support development of large J2EE applications. Existing tools were found to be too cumbersome to integrate with complex build systems, and often required specialized development and/or runtime environments that were not compatible with target J2EE Containers. Another feature that we found lacking in other tools was simple, source-level coverage reporting - the kind that is most useful to Developers.

Why the name "Clover"?
Clover is actually a shortened version of the tool's original name, "Cover Lover", from the nick name that the tool's author gained while writing Clover ("Mr Cover Lover").

Why is Clover so much cheaper than over Coverage Tools?
Clover provides code coverage features comparable with much higher priced tools. Clover was originally developed as an internal tool, so we don't have huge development costs to try to recover. We also firmly believe that Code Coverage should be a developer activity, not a "tester" activity, so we want to make the entry cost low.

Why does Clover use Source Code Instrumentation?
Source code instrumentation is the most powerful, flexible and accurate way to provide code coverage analysis. However, source code instrumentation can be tricky, primarily because it can be difficult to integrate into a build system. Source trees need to be copied, instrumented, and then fed to the compiler in a transparent manner. Clover overcomes this problem by tightly integrating with Ant - the defacto standard for building Java projects. Integrating Clover into your build system is as easy as setting a few Ant properties before compilation.
The three most common methods of measuring (Java) code coverage are:

    JVMDI/PI. This runtime-only approach utilises the debugging architecture provided by the JVM to monitor execution status of your program and infer coverage metrics.
    Bytecode instrumentation. This approach involves post-processing Java object code (bytecode) either at compile-time, or at runtime via a specialized classloader, to introduce a coverage gathering mechanism.
    Source code instrumentation. This approach, employed by Clover, involves pre-processing Java source code at compile-time to introduce a coverage gathering mechanism.
The following table compares the possible featureset of code coverage tools utilising the different implementation strategies listed above.
Possible featureJVMDI/PIBytecode instrumentationSource code instrumentation
gathers method coverageyesyesyes
gathers statement coverageline onlyindirectlyyes
gathers branch coverageindirectlyindirectlyyes
can work without sourceyesyesno
requires separate buildnonoyes
requires specialized Runtimeyesyesno
gathers source metricsnonoyes
view coverage data inline with sourcenot accuratenot accurateyes
source level directives to control coverage gatheringnonoyes
control which entities are reported onlimitedlimitedyes
compilation timeno impactvariablevariable
runtime performacehigh impactvariablevariable
Container friendlynonoyes

Will Clover integrate with my IDE?
Clover should work happily with any IDE that provides integration with the Ant build tool. We've tested Eclipse, IDEA, JBuilder, NetBeans, and JEdit. Clover Coverage Reporting integration into IDEs is something we are looking at for future releases of Clover.

What 3rd Party libraries does Clover utilise?
Clover makes use of the following excellent 3rd party libraries:
Jakarta Velocity 1.2Templating engine used for Html report generation.
Antlr 2.7.1 & accompanying Java 1.3 grammarA public domain parser generator. Note that to prevent possible version conflicts, Clover uses a repackaged version of Antlr that is bundled in the Clover jar file.

Troubleshooting Clover

Clover has been carefully tested on many hundreds of thousands of lines of java source code. Two questions to ask yourself first when troubleshooting Clover:

    Does my code compile and run as expected without Clover?
    You need to ensure that your project compiles and runs as expected before attempting to use Clover.
    Am I using the latest version of Clover?
    The latest version of Clover incorporates many bugfixes and improvements.
If the answers in this section don't fix the problem you are encountering, please contact us and we'll be happy to help.

When using Clover, I get "Compiler Adapter 'org.apache.tools.ant.taskdefs.CloverCompilerAdapter' can't be found." or similar. Whats going wrong?
You need to install the clover.jar into ANT_HOME/lib.

When using Clover, I get a java.lang.NoClassDefFoundError when I run my code. Whats going wrong?
This probably indicates that you do not have clover.jar in your runtime class path. See Clover and classpaths.

I get a java.lang.ArrayIndexOutOfBoundsException when I run my Clovered code. Whats going wrong?
The coverage database generated by Clover is out of sync with the instrumented code. Try deleting the coverage database (referenced by ${clover.initstring}) and recompiling with Clover switched on. This will force Clover to rebuild a new coverage database.

When I run one of the reporters from Ant under jdk1.4, I get a java.lang.NoClassDefFoundError.
This is not a bug in Clover, but rather a product of some Ant/Java classloader funkiness under jdk1.4. See Ant bug 3158 for a technical description of the problem. The simple workaround is set the fork="true" attribute on the <java> task that launches the reporter.

Why do I get 0% coverage when I run my tests and then a reporter from the same instance of Ant?
This occurs because Clover hasn't had a chance to flush coverage data out to disk. By default Clover flushes coverage data only at JVM shutdown or when explicitly directed to (using a inline directive). The simplest thing to do is to use the fork="true" attribute when running your tests. The tests will be then run in their own JVM, and the coverage data will be flushed when the that JVM exits. Alternatively, you can use interval-based flushing by setting the optional clover.flushpolicy property.

When I run Clovered code I get a java.lang.NullPointerException that doesn't occur when I run without Clover.
Clover can (very rarely) cause problems if you have any circular classloading dependencies in your code. If you run into this problem, it can be solved by directing Clover to use class-based instrumentation for the classes in question. You can either put a ///CLOVER:USECLASS source level directive at the top of the source file, or set the clover.useclass.includes Ant property.

I get an java.lang.OutOfMemoryError when compiling with Clover turned on.
Instrumenting with Clover increases the amount of memory that the compiler requires in order to compile. To solve this problem, you need to give the compiler more memory. Increasing the memory available to the compiler depends on how you are launching the compiler:
If you are using the "in-process" compiler (the <javac> task with the "fork" attribute set to false), you will need to give Ant itself more memory to play with. To do this, use the ANT_OPTS environment variable to set the heap size of the JVM used to run Ant:

export ANT_OPTS=-Xmx256m
If you are using an external compiler (the <javac> task with the "fork" attribute set to true), you can set the memoryInitialSize and memoryMaximumSize attributes of the javac task:
<javac srcdir="${src}"
          destdir="${build}"
          fork="true"
	  memoryInitialSize="128m"
	  memoryMaximumSize="256m"
  />

For some statements in my code Clover reports "No Coverage information gathered for this expression". What does that mean?
Clover will not measure coverage of a conditional expression if it contains an assignment operator. In practice we have found this only a minor limitation. To understand why Clover has this limitation, consider the following (very contrived) code fragment:

  1  public int foo(int i) {
  2    int j;               
  3    if ((j = i) == 1) {   
  4      return j;    
  5    }
  6    return 0;
  7  }

  at (2) the variable "j" is declared but not initialised.
  at (3) "j" is assigned to inside the expression
  at (4) "j" is referenced.

During compilation, most compilers can inspect the logic of the conditional at (3) to determine that "j" will be initialised by the time it is referenced (4), since evaluating the expression (3) will always result in "j" being given a value. So the code will compile. But Clover has to rewrite the conditional at (3) so that it can measure coverage, and the rewritten version makes it harder for compilers to infer the state of "j" when it is referenced at (4). This means that the instrumented version may not compile. For this reason, Clover scans conditionals for assignment. If it one is detected, the conditional is not instrumented.

 

© 2002 Cortex eBusiness. All rights reserved.
Java is a trademark of Sun Microsystems, Inc