Usage

Getting Started

The first thing to do is to create a Clover database. To do this, you must either do:

  mvn clover2:instrument

or

  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          [...]
        </configuration>
        <executions>
          <execution>
            [...]
            <goals>
              <goal>instrument</goal>
            </goals>
            [...]
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

This instruments all sources using Clover so that a Clover database is created (or if it already exists, the plugin will simply use it and add data on top of the existing one). When you execute your tests the instrumented code will start generating logs into the Clover database. These logs can then be used for Test Coverage Percentage checks, for report generation or for logging.

Note that the Clover plugin takes great care not to mix the instrumented code nor any artifact generated from it with main production sources and artifacts. This is the reason why you may see your tests executed twice: once for the production sources and once for the Clover-instrumented sources.

Back to top.

Controlling files to instrument

By default all Java files are included during the instrumentation. To specify inclusion and exclusion use the includes and excludes configuration elements as shown in this example:

  <plugin>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-clover2-plugin</artifactId>
    <configuration>
      <includes>
        <include>**/api/**/*.java</include>
        <include>some/path/MyFile.java</include>
        [...]
      </includes>
      <excludes>
        <exclude>**/*Test/java</exclude>
        [...]
      </excludes>
[...]

Back to top.

Checking test coverage

In order to check for a test coverage percentage and fail the build in case of non-compliance, you'll need to configure the Clover plugin to tell it what test coverage threshold you wish to use:

  mvn clover2:check -Dmaven.clover.targetPercentage=50%

or

  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          <targetPercentage>50%</targetPercentage>
        </configuration>
        <executions>
          <execution>
            <phase>verify</phase>
            <goals>
              <goal>check</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

In this example you've told Maven to run clover2:check whenever the verify phase is reached (this will be the case if you run mvn install for example).

Furthermore, you specified that the targetPercentage is 50%, meaning the test must result to at least 50% test coverage percentage to pass. If the targetPercentage was not specified, the default value of 70% will be used.

However, as previously mentioned, Clover needs an existing Clover database. Thus, a call to clover2:instrument may be neccessary:

  mvn clover2:instrument clover2:check -DtargetPercentage=50%

or

  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          <targetPercentage>50%</targetPercentage>
        </configuration>
        <executions>
          <execution>
            <phase>verify</phase>
            <goals>
              <goal>instrument</goal>
              <goal>check</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

Note: The clover2:check goal will also check the test percentage coverage for merged Clover databases if any is found (see the Aggregating Clover Reports section for more on that).

There are some special cases where you'd want the build not to fail even though the TPC is below the expected threshold (for example to let the build continue so that you can see the results of other checks prior to fixing the TPC). There's a failOnViolation configuration property for this which you can also run on the command line as follows:

  mvn clover2:instrument clover2:check -Dmaven.clover.targetPercentage=50% -Dmaven.clover.failOnViolation=false

Back to top.

Using block contexts

Clover allows specifying block contexts (i.e. elements to be excluded from the Test Percentage Coverage). To configure a block context use the contextFilters element in the reporting section. For example to exclude try and static block contexts, you would write:

[...]
  <reporting>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          <contextFilters>try,static</contextFilters>
        </configuration>
[...]

Note that the contextFilters element has to be specified within the reporting section and will not work if you specify it in the build section.

Back to top.

Using Clover with different JDK versions

If your code is using JDK 1.4 or JDK 1.5 specific keywords, you'll need to configure the Clover plugin. For example for JDK 1.4:

  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          <jdk>1.4</jdk>
[...]

Back to top.

Specifying a Clover flush policy

If you want to specify the Clover flush policy that the plugin should use, then specify it in the plugin's configuration. Valid policies are threaded, directed and interval.

For example to use a threaded policy with a flush interval of 5000 ms you would write:

  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          <flushPolicy>threaded</flushPolicy>
          <flushInterval>5000</flushInterval>
[...]

Back to top.

Generating a Clover report

To generate a Clover report, simply execute the following command:

mvn clover2:clover

Also, you may want to generate a Clover Report everytime you generate site for your maven project (i.e. mvn site):

<project>
  [...]
  <reporting>
    <plugins>
      [...]
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          [...]
        </configuration>
      </plugin>
    </plugins>
  </reporting>
[...]

But just like the clover2:check goal, the clover2:clover goal also needs an existing Clover database. Thus, if if it still does not exist, a call to clover2:instrument must first be made:

mvn clover2:instrument clover2:clover

or

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          [...]
        </configuration>
        <executions>
          <execution>
            <phase>pre-site</phase>
            <goals>
              <goal>instrument</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  [...]
  <reporting>
    <plugins>
      [...]
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          [...]
        </configuration>
      </plugin>
    </plugins>
  </reporting>
[...]

Note that in the above example that clover2:instrument was bound to the pre-site phase. This is done to ensure that a Clover database is generated before the report executes.

Back to top.

Specifying report formats

By default the Clover plugin will generate a HTML report. If you want to generate a PDF or XML report, or if you simply do not want to generate the HTML report use the generateHtml, generatePdf and generateXml configuration elements. By default the generateHtml element is set to true.

For example if you wish to generate the PDF and XML reports you would use:

[...]
  <plugin>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-clover2-plugin</artifactId>
    <configuration>
      <generatePdf>true</generatePdf>
      <generateXml>true</generateXml>
    </configuration>
  </plugin>
[...]

Note that only the HTML report gets a link in the "Project Reports" section in generated menu on the site. If you want to link the PDF or XML reports you'll need to do that by modifying your site.xml. For example:

[...]
  <menu name="Other Reports">
    <item name="Clover PDF" href="clover/clover.pdf"/>
    <item name="Clover XML" href="clover/clover.xml"/>
  </menu>
[...]

If you do not want to generate the HTML report then you should not configure the Clover plugin in the reporting section as this section is for plugins which generate HTML reports. In that case, simply bind the clover2:clover goal to the site phase in the build section. For example:

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          <generateHtml>false</generateHtml>
          <generatePdf>true</generatePdf>
          <generateXml>true</generateXml>
        </configuration>
        <executions>
          <execution>
            <phase>site</phase>
            <goals>
              <goal>instrument</goal>
              <goal>clover</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
[...]

Back to top.

Generating historical reports

Generating historical reports is done in the same manner as you generate a standard Clover report but in addition you need to set the generateHistorical configuration property to true (it's false by default). For example:

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          <generateHistorical>true</generateHistorical>
          [...]
        </configuration>
        [...]
      </plugin>
    </plugins>
  </build>
[...]

Now this will generate a Clover historical report only if you have saved Clover historical savepoints. In order to save a Clover savepoint, run the clover2:save-history goal. It's up to you to decide when you want to call this goal.

For example you could call it every time a build is executing on your CI server, or you could call it at every project release, etc. The location of the history directory for saving the savepoints is controlled by the historyDir configuration property, which points to $project.build.directory/clover/history by default.

It is recommended to use another location that will not get erased by a mvn clean. For example:

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          <generateHistorical>true</generateHistorical>
          <historyDir>${myHistoryDir}</historyDir>
          [...]
        </configuration>
        [...]
      </plugin>
    </plugins>
  </build>
[...]

Where myHistoryDir could be a Maven property that you define in a profile.

The historical report is generated in the $project.build.dir/clover/history/historical.html file. If you wish to link this report to the generated web site you'll need to modify your site.xml and add the link by hand. The technical reason is that Maven only supports one report per MOJO. For example:

[...]
  <menu name="Other Reports">
    <item name="Clover History" href="clover/history/historical.html"/>
  </menu>
[...]

Back to top.

Aggregating Clover Reports

Note: There's currently a bug in Maven2 which results in the clover aggregation not working properly. More specifically the aggregate goal requires an existing Clover database and the first time your run mvn site it won't find the generated children databases as they'll be produced after it executes. It'll work the second time though. Just ensure that you run the aggregate goal after you've generated the children Clover databases.

You can aggregate children modules Clover databases into a single merged database by running the clover2:aggregate goal. This For example if you have the following project layout:

myproject
 |-- project1
 |   `-- pom.xml
 |-- project2
 |   `-- pom.xml
 `-- pom.xml

Then, ensure that your myproject/pom.xml contains the following:

<project>
  [...]
  <reporting>
    <plugins>
      [...]
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
      </plugin>
    </plugins>
  </reporting>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <executions>
          <execution>
            <phase>pre-site</phase>
            <goals>
              <goal>instrument</goal>
              <goal>aggregate</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
[...]

When you run mvn site in myproject/, the plugin will instrument your sources, run your tests, aggregate the different Clover database generated for each build module (i.e. project1 and project2) and generate an aggregated Clover report in the site for the myproject project.

Alternatively, you can execute

mvn clover2:aggregate clover2:clover

or if there is no existing Clover database:

mvn clover2:instrument clover2:aggregate clover2:clover

Note that you can control the location of the merged Clover database by using the cloverMergeDatabase configuration property.

Back to top.

Getting information on an existing Clover database

You can dump information about your project's Clover database (after it has been populated) by running mvn clover2:log.

Here's an example of an output:

[INFO] [clover2:log]
[INFO] Clover Coverage Report
Coverage Timestamp: Tue Oct 03 12:54:52 CEST 2006


Coverage Overview -
      Methods: 2/3 (66,7%)
   Statements: 2/3 (66,7%)
 Conditionals: 1/2 (50%)
        TOTAL: 62,5%

Back to top.

Specifying a custom license file

The Clover plugin provides a default evaulation license. However if you continue to use Clover you'll need your own license (they are free for open source/non-commercial project but you'll need to contact Atlassian to get a license). To use your license specify it using a licenseLocation configuration element. For example if you wanted to automatically execute the check goal when you type mvn install and if you wanted to use your license located in $basedir/src/test/clover/myclover.license you would use:

  <build>
    <plugins>
      <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>maven-clover2-plugin</artifactId>
        <configuration>
          <licenseLocation>${basedir}/src/test/clover/myclover.license</licenseLocation>
        </configuration>
        <executions>
          <execution>
            <configuration>
              <targetPercentage>50%</targetPercentage>
            </configuration>
            <phase>verify</phase>
            <goals>
              <goal>instrument</goal>
              <goal>check</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

Important note: The licenseLocation element needs to be defined in the global configuration element and not in the configuration element under the execution tag.

Instead of specifying a file, you can also specify either a URL or a relative path inside a JAR (to learn how to use this feature, refer to the Checkstlye plugin documentation.

As of version 4.0 of the plugin, you can also use the license element to embed a license directly in your pom.xml.

Back to top.