Index
User Guide
FAQ
Clover Website
|
|
Clover User Guide
Contents:
Introduction
This user guide covers the basics of getting up and running with Clover. It covers basic integration, configuration and reporting scenarios. It assumes that the user is familiar with the Jakarta Ant build tool, and with modifying Ant build files. For help with Ant, see http://jakarta.apache.org/ant/manual/index.html. For Clover troubleshooting information, see the FAQ.
Clover Quick Start Guide
Clover works by instrumenting a copy of your java source before compilation. Because Clover is
tightly integrated with Ant, modifying a build file to use Clover is straightforward. Because of
the flexibility of Ant, the technique described here is only one of many possible ways to integrate
Clover with Ant.
- ensure you are using a recent version of Ant (v1.4.1 or greater)
- if you haven't done so already, download Clover. Unpack the Clover archive to a directory.
- copy
<CLOVER_HOME>/lib/clover.jar into <ANT_HOME>/lib
- edit build.xml for your project:
- add a property that tells Clover a path to write coverage data (Clover will create
and write to this file during compile-time, and write coverage data along side it at runtime):
<property name="clover.initstring" location="/tmp/mycoverage.db"/>
- add a target to switch on Clover:
<target name="with.clover">
<property name="build.compiler" value="org.apache.tools.ant.taskdefs.CloverCompilerAdapter"/> </target>
- add a target to run a clover report:
add a path element that holds the classpath for Clover
(edit the path to point to the Clover jars on your filesystem):
<path id="clover.classpath"> <pathelement path="<CLOVER_HOME>/lib/clover.jar"/> <pathelement path="<CLOVER_HOME>/lib/velocity.jar"/> <-- only needed if you are using html reporter -->
</path>
to launch the Swing viewer, use:
<target name="clover.report"> <java classname="com.cortexeb.tools.clover.reporters.jfc.Viewer" fork="yes"> <arg line="${clover.initstring}"/> <classpath refid="clover.classpath"/> </java> </target>
- OR - for html reporting, use (change the outputdir to a path where Clover should put the generated html):
<target name="clover.report"> <java classname="com.cortexeb.tools.clover.reporters.html.HtmlReporter" fork="true"> <arg line="--outputdir /tmp/clover_html --showSrc --initstring ${clover.initstring} --title 'My Project'"/> <classpath refid="clover.classpath"/> </java> </target>
- OR - for xml reporting, use (change the outfile to a file where Clover should write the xml file):
<target name="clover.report"> <java classname="com.cortexeb.tools.clover.reporters.xml.XmlReporter" fork="true"> <arg line="--outfile /tmp/coverage.xml --initstring ${clover.initstring} --title 'My Project'"/> <classpath refid="clover.classpath"/> </java> </target>
- OR - for simple emacs-style reporting to the console, try:
<target name="clover.report"> <java classname="com.cortexeb.tools.clover.reporters.emacs.EmacsCloverReporter"> <arg line="--level method --initstring ${clover.initstring} --title 'My Project'"/> <classpath refid="clover.classpath"/> </java> </target>
- Save your build.xml
- Now you can build your project with Clover turned on by adding the "with.clover" target to the list of targets to execute. For example (if your compile target is named 'build' and your unit test target is named 'test'):
ant with.clover build test
note: if when you run this command problems occur, chances are clover is not in the runtime classpath. See the section below on Clover and classpaths.
- To generate a Clover coverage report:
ant clover.report
Clover and classpaths
In your javac task, if you have set the attribute includeAntRuntime="no" , you will need to add the Clover jar to the compilation classpath. The easiest way to achieve this is to add the Clover classpath reference to javac tasks, like this:
<javac ...>
... <classpath refid="clover.classpath"/> </javac>
Similarly, clover.jar will need to be in the runtime classpath whenever you run Clovered code. This is quite often as simple as adding a classpath reference (like the one above) to execution tasks (like <java> or <junit>). For other projects, particularly Hosted Applications, you must ensure that clover.jar is deployed along with your clovered code.
Compile-time properties
Clover's instrumentation process is controlled by the set of Ant properties described below. Note that all but one
of these properties are optional - the only required property is clover.initstring .
Property: | clover.initstring |
Required? | YES |
Values: | valid & writable file path |
Description: The string used to initialise and access the Clover
coverage database. You must set this to a file that Clover can create and write
to at compile-time. Clover will also create and write to a series of coverage data
files during runtime -these will be created in the parent directory of the file specified above. The
specified path must resolve to the same location at both compile-time
and runtime. For this reason, using an absolute path is the safest option. |
|
Property: | clover.enable |
Required? | NO |
Values: | true,false |
Default: | true |
Description: Setting this property to false disables Clover. This is convenient
if you want to turn Clover on and off without using the build.compiler property |
|
Property: | clover.compiler |
Required? | NO |
Values: | see Ant Javac doc |
Default: | Ant default |
Description: The compiler to delegate to once instrumentation is complete. If you need to specify a non-default
compiler for the javac task (normally done by setting the build.compiler Ant property) then you can
use clover.compiler to achieve the this. |
|
Property: | clover.preserve |
Required? | NO |
Values: | true,false |
Default: | false |
Description: Setting this property to true tells Clover to preserve the instrumented source. This is useful primarily for debugging Clover. The default is false - the instrumented source is deleted after
compilation. |
|
Property: | clover.tmpdir |
Required? | NO |
Values: | A valid and writable directory path |
Default: | Obtained using java.io.File.createTempFile() |
Description: The directory that Clover will use to write an instrumented copy of your source code. |
|
Property: | clover.excludes, clover.includes |
Required? | NO |
Values: | see Ant PatternSet doc |
Default: | See below |
Description: A comma or space separated list of Ant patternset matching expressions that determines which source
files get included or excluded at the Clover instrumentation step. Note that files that are excluded are
still compiled - just not instrumented by Clover.
If neither property is set, all files specified in the javac task will be processed by Clover.
If only clover.includes is set, files matching one of the specified include patterns will be
instrumented.
If only clover.excludes is set, all files specified in the javac task will be instrumented, except files matching any of
the specified excludes patterns.
If both properties are set, excludes override includes. |
|
Property: | clover.useclass.includes |
Required? | NO |
Values: | see Ant PatternSet doc |
Default: | empty |
Description: A comma or space separated list of Ant patternset matching expressions that determines which source
files get instrumented using the "inner class" approach. This is useful for classes that are interface-sensitive (like CMP beans) and for resolving (rare) circular classloading problems. |
|
Property: | clover.flushpolicy |
Required? | NO |
Values: | directed, interval |
Default: | directed |
Description: This property controls how Clover flushes coverage data to disk
during a coverage run. Regardless of this setting, Clover will automatically attempt to register a
shutdown hook that will flush coverage data on JVM shutdown. See Flushing at JVM shutdown below.
When the value of this property is directed , Clover will only insert code to flush coverage data when explicitly directed to by the occurance of a
Clover FLUSH directive in the source. See Clover source level directives.
When the value of this property is interval , Clover will flush at most every n milliseconds, where n is the value of the
clover.flushpolicy.interval property.
Note: Depending on your application, small values of n can have a significant performance impact.
Note: Clover will still insert flush code when a FLUSH directive is encountered in the source.
Flushing at JVM shutdown
Clover automatically attempts to add a shutdown hook that will flush coverage data on JVM shutdown.
On pre-1.3 JVMs this will have no effect, and you must use one of the flushing policies above. Note also
that some server containers impose security settings that prevent the registration of shutdown hooks.
See Clover and Hosted Applications. |
|
Clover source-level directives
Clover supports a number of directives that you can use in your source to control instrumentation.
Directives can be on a line by themselves, or part of any valid single or multi-line java comment. The
supported directives are:
///CLOVER:ON
///CLOVER:OFF
Switch Clover instrumentation on/off. This might be useful if you don't want Clover to instrument a
section of code for whatever reason. Note that the scope of this directive is the current file only.
///CLOVER:FLUSH
Clover will insert code to flush coverage data to disk. The flush code will be inserted as soon as possible
after the directive.
///CLOVER:USECLASS
Clover will use a static holder class rather than a static member variable to support instrumentation for
the current file. The directive must occur before the first top level class declaration in the file. This
directive is useful when you don't want Clover to change the public interface of your
class (in EJB compilation for example).
Clover and Hosted Applications
We have successfully used Clover with applications hosted on serveral applications servers, including JBoss, Weblogic 5.1,
and others. When using Clover with hosted apps, the following points should be considered:
- At the moment, Clover needs read and write access to the same filesystem at compile-time and runtime.
This means that where-ever clovered code is loaded and executed, it must be able to access the file
specified at compile-time in the
clover.initstring property. It must also be able
to create and files in the same directory. Some app servers block access to the file system for hosted
applications. You may need to change the server security settings to loosen this restriction.
- The Clover runtime jar must be deployed alongside any clovered code.
- Clover will attempt to register a JVM shutdown hook to flush coverage data when the JVM shuts down. Some
app servers (e.g. Weblogic 5.1) block access to this facility by default. To workaround this, you can
either use another
clover.flushpolicy , or loosen the server
server security settings to allow registration of shutdown hooks.
Using the Reporters
Three reporters currently exist for Clover.
Swing Viewer
The Swing Coverage viewer supports interactive source level coverage browsing. To run it from Ant, use something like:
<target name="clover.report"> <java classname="com.cortexeb.tools.clover.reporters.jfc.Viewer" fork="yes"> <arg line="${clover.initstring}"/> <classpath refid="clover.classpath"/> </java> </target>
Emacs Reporter
The Emacs Reporter can be used for basic coverage reporting to the console. To run it from Ant, use something like:
<target name="clover.report"> <java classname="com.cortexeb.tools.clover.reporters.emacs.EmacsCloverReporter"> <arg line="--level method --initstring ${clover.initstring} --title 'My Project'"/> <classpath refid="clover.classpath"/> </java> </target>
Html Reporter
The Html Reporter produces html-based reports of your coverage data. The easiest way to run the Html Reporter is by creating an appropriate Ant target in your build file:
<target name="clover.report"> <java classname="com.cortexeb.tools.clover.reporters.html.HtmlReporter" fork="true"> <arg line="--outputdir /tmp/clover_html --initstring ${clover.initstring} --title 'My Project'"/> <classpath refid="clover.classpath"/> </java> </target>
Parameters supported by the Html reporter:
-o, --outputdir <dir> | output directory for generated html. Will be created if it doesn't exist. |
-i, --initstring <string> | The clover database to report on. |
-t, --title <string> | (optional) title to put on the top of report. |
-bw | (optional) Don't color syntax-hilight source - smaller html output. |
-e, --showempty | (optional) show classes/packages in the report even if they don't have any statements, methods or conditionals. default is false |
-n, --nocache | (optional) insert no-cache browser directives in html output. |
-h, --hidesrc | (optional) don't render source code. |
-l, --ignore <string> | (optional) comma or space separated list of blocks to ignore when generating coverage reports. Most useful one is "catch". Valid values are "static", "instance", "constructor", "method", "switch", "while", "do", "for", "if", "else", "try", "catch", "finally", "sync" |
-c, --orderby <string> | (optional) comparator to use when listing packages and classes. Valid values are "alpha" - alphabetic, "desc" - coverage descending, "asc" - coverage ascending. default is "asc". |
-d, --debug | (optional) switch logging to debug level |
-v, --verbose | (optional) switch logging to verbose level |
XML Reporter
The Xml Reporter produces summary XML reports of your coverage data. To run it from Ant, use something like:
<target name="clover.report"> <java classname="com.cortexeb.tools.clover.reporters.xml.XMLReporter" fork="true"> <arg line="--outfile coverage.xml --initstring ${clover.initstring} --title 'My Project'"/> <classpath refid="clover.classpath"/> </java> </target>
Parameters supported by the Html reporter:
-o, --outfile <dir> | output file for XML |
-i, --initstring <string> | The clover database to report on. |
-t, --title <string> | (optional) title to put on the top of report. |
-d, --debug | (optional) switch logging to debug level |
-v, --verbose | (optional) switch logging to verbose level |
|
|