Using Distributed Per-test Coverage with Clover-for-Ant

Working with Distributed Applications

On this page

Still need help?

The Atlassian Community is here for you.

Ask the community

This page contains instructions on how to collect per-test coverage from a set of functional tests, which run in multiple JVMs (Java Virtual Machines). This may be necessary when starting a web server with the Jetty Runner or Tomcat Tasks, for example.

On this page:

General Overview

Clover collects per-test coverage for tests running in a separate JVM by sending messages using the tcp protocol. The JVM hosting the tests is the 'Clover Server' and the JVM(s) hosting the application are the 'Clover Clients'. The 'Clover Server' ( ie. the JVM running your tests) needs to be marked as such via a System Property: 'clover.server=true'. If this property is not set, or is set to 'false', the JVM will be in 'Clover Client' mode.

If you are testing multiple projects on the same machine at the same time (such as in a Continuos Integration environment), you will need to ensure a unique port for each build is reserved and configured. By default, Clover starts a socket server on port 1198.

Distributed per-test coverage will give you insight as to what functional tests covered what application code. It also allows you to drastically reduce test execution time by using Clover's Test Optimization to only run the tests for code that was modified since the previous build.

To configure Clover for collection of per-test coverage from distributed builds, you have two options:

  1. Recommended: By setting a System Property on the JVM running your tests and the JVM hosting your application (e.g. the webserver)
  2. By configuring Clover before instrumenting (clover-setup, clover-instr) your source files - and setting a System property on the test JVM (Only Recommended if setting a System Property on your webserver poses a problem.)

Option 1. Enabling Distributed Coverage at Runtime

Once your Clover-instrumented application has been deployed, and your tests have been instrumented and compiled with Clover, distributed per-test coverage can be enabled and configured at runtime using just two System Properties.

Both JVMs require the 'clover.distributed.coverage' property set to ON, and the JVM running the tests require the 'clover.server' property set to 'true'.

 

(lightbulb) TIP: the clover.distributed.coverage=ON takes default settings (host=localhost, port=1198, timeout=5000ms, numClients=0, retryPeriod=1000ms, name=clover.tcp.server). In case when you cannot use default settings, you can pass specific value for any of attributes using the "key=value" syntax passed as clover.distributed.coverage value:

  • host - host name of the "Clover Server"
  • port - port on which the Clover will listen
  • numClients - number of "Clover Clients" to connect until server starts test execution
  • timeout - connection timeout in milliseconds
  • retryPeriod - interval between connection retries in milliseconds
  • name - name of the Clover server service (URL is host:port/name)

Example:

-Dclover.distributed.coverage=host=myhost;port=7777;numclients=2

 

For the following examples, we are using the Jetty Runner to start the Jetty Webserver, and the Ant JUnit Task to run the tests.

Setting the System Properties in the Ant JUnit Task

<junit fork="true" forkmode="once" showoutput="true" printsummary="true">
        <sysproperty key="clover.server" value="true"/>
        <sysproperty key="clover.distributed.coverage" value="ON"/>
        ...
</junit>

Setting a System Property in the Java task that starts the WebServer

The JVM running your webserver also requires the clover.distributed.coverage property set to ON.

 <java jar="${jetty.jar}" fork="true">
	...
        <jvmarg value="-Dclover.distributed.coverage=ON"/>
</java>

If you are unable to set a System Property on the JVM running your webserver, use the second approach described below.

Option 2. Configuring Distributed Coverage at Instrumentation Time

It is sometimes more convenient to enable distributed Coverage when you enable Clover - before instrumentation of your source code.
The following approach removes the need to set any system properties at all on the JVM running the WebServer.

Step 1: Activate the Distributed Per-Test Coverage Feature

Both the <clover-setup> and <clover-instr> tasks can be configured with this nested element:

<distributedCoverage/>

If this element is present, then Clover will run in 'distributed mode' at test time. If you wish to modify any configuration options such as the port to listen on, or the number of clients expected to attach to the testing session, you can specify these as attributes on the <distributedCoverage> element like so:

<clover-setup>
  <distributedCoverage port="1234" numClients="1"/>
</clover-setup>

This will enable distributed per-test coverage to be collected. Please see the documentation for the <distributedCoverage/> element for more options.

Step 2: Specify the 'clover.server' property on JVM running the Tests

Add the clover.server system property to the JUnit or TestNG Ant task configuration, and ensure the forkMode parameter is set to 'once':

e.g.

<junit fork="true" forkmode="once" showoutput="true" printsummary="true">
        <sysproperty key="clover.server" value="true"/>
        ...
</junit>

If you have specified the numClients option to something greater than 0, your tests can be started prior to starting the webserver. Clover will wait until numClients have connected to the testing session before allowing the tests to start running.

About Distributed Per-Test Coverage

About Test Optimization

Last modified on May 26, 2016

Was this helpful?

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