Configuring Clover's short name in .m2/settings.xml

Before you get started, add this to your .m2/settings.xml file so you can reference Clover by its short name clover.

<pluginGroups>
    <pluginGroup>org.openclover</pluginGroup>
</pluginGroups>

 

Running Clover goals from the command line

The quickest and easiest way to try Clover is from the command line, for example:

mvn clean clover:setup test clover:aggregate clover:clover

 

Installing Clover in pom.xml

Install Clover-for-Maven by adding it to your Maven build file (pom.xml):

  1. Set up your pom.xml by adding:

    pom.xml
    <build>
        <plugins>
            <plugin>
                <groupId>org.openclover</groupId>
                <artifactId>clover-maven-plugin</artifactId>
                <version>${clover.version}</version>     
            </plugin>
        </plugins>
    </build>
    

    (info) Either change ${clover.version} to the current Clover version, or define a property in your pom.xml that sets this value.

  2. Now, simply invoke Clover with Maven on the command line.

    mvn clean clover:setup test clover:aggregate clover:clover

    This will instrument your sources, build your project, run your tests and create a Clover coverage report in the target/site/clover directory.

    You can also have Clover run as part of your build by adding Clover's goals in pom.xml.

 

There are four basic parts executed when recording code coverage with Clover.

  1. The clover:setup goal will instrument your Java source files.
  2. The test phase is Maven's standard command for running a unit test phase.
  3. The clover:aggregate goal is used for merging coverage data generated by multi-module projects.
  4. The clover:clover goal generates an HTML, XML, PDF or JSON report.

Running Goals via pom.xml

The goals described above can be executed by specifying them in your pom.xml.

To generate a Clover report when you run the site goal:

<project>
  <reporting>
    <plugins>
      <plugin>
        <groupId>org.openclover</groupId>
        <artifactId>clover-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </reporting>
</project>

To instrument your sources whenever you build:

<project>
  <build>
    <plugins>
      <plugin>
        <groupId>org.openclover</groupId>
        <artifactId>clover-maven-plugin</artifactId>
        <executions>
          <execution>
            <phase>generate-sources</phase>
            <goals>
              <goal>instrument</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

To include aggregation of child modules:

<project>
...
  <build>
        <plugins>
            <plugin>
                ...
                <executions>
                    <execution>
                        <id>main</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>instrument</goal>
                            <goal>aggregate</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>site</id>
                        <phase>pre-site</phase>
                        <goals>
                            <goal>instrument</goal>
                            <goal>aggregate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
...

 

Using clover:setup vs clover:instrument vs clover:instrument-test

The clover:setup goal performs instrumentation in the main build life cycle, therefore it's not recommended to use it together with 'install' or 'deploy' goals (unless this is your intention). The benefit of this approach is that build is made only once. Furthermore, clover:setup supports instrumentation of Groovy code (while clover:instrument does not).

 

The clover:instrument goal can be used if you need to actually install or deploy non-instrumented project's artifact and have Clover run at the same time. This will fork a custom build life cycle and run it till the "verify" phase and cause each Clover artifact to contain the -clover classifier. A drawback of this approach is that the build and tests are performed twice.

(warning) This goal has one limitation - due to a fact that Maven allows to have only one classifier for an artifact, the 'clover' suffix may not be added if you use own classifiers. It means that it can happen that instrumented code (e.g. myapp-1.0-tests-clover.jar) will be installed using its original name (e.g. myapp-1.0-tests.jar). Using maven-install-plugin with <installAtEnd>true</installAtEnd> may help as it re-installs non-instrumented JARs at the end of the build.

 

The clover:instrument-test goal also forks a custom build cycle, but runs it till the "test" phase. Thanks to this, instrumented artifacts are not installed.

How to manage instrumented code

As Clover integration produces instrumented classes, we recommend to ensure that you do not install them to production (for instance: 'mvn deploy' to public repository, 'scp' to an application server running on production, etc). Having instrumented code in such location(s) is usually not desired.

Common practices to ensure proper separation of instrumented and non-instrumented classes and JARs are:

  • configure Clover in a profile in your pom.xml
  • create a dedicated build plan in which Clover is enabled
  • use clover:setup to run tests only (e.g. "mvn test" or "mvn verify")
    • in case you must run "mvn install", use different location of local artifact cache (e.g. ~/.m2/repository-clover)
    • in case you must run "mvn deploy", use different URL for uploading artifacts (i.e. a separate binary repository)
  • use clover:instrument or clover:instrument-test if you need to produce both instrumented and non-instrumented code
    • keep in mind that Maven does not support multiple classifiers for an artifact