This manual presents how to configure Clover in order to get code coverage for web applications - and this issue can actually split into several problem areas:
Flushing coverage data in application container
By default, Clover dumps coverage data at JVM shutdown. In case when your application sever is never shut down, you have to change the flush policy during instrumentation and use the "interval" or "threaded" option. See:
- clover-instr or clover-setup task and theirs flushpolicy, flushinterval attributes (for Ant)
- clover:instrument or clover:setup and their flushPolicy, flushInterval parameters (for Maven)
Providing necessary permissions in restricted security environments
Clover requires permissions to read and write files on disk, read properties, register to JVM shutdown hook. It can happen that your application container has security restrictions applied and you have to grant Clover necessary permissions. See:
Configuring distributed code coverage
In case when:
- your tests are being executed in a different JVM than application code called by them (for example JUnits executed during build calls servlets deployed on Tomcat, or EJBs on JBoss) and
- you're interested in the per-test coverage feature (i.e. which test methods have covered which business methods) or you're interested in the test optimization feature
then your project must be configured with a distributed coverage option. See:
- Working with Distributed Applications
Application based on the Google Web Toolkit
Running in the 'test' or 'integration-test' phase
Depends on whether your build is running tests in 'test' and/or 'integration-test' phase as well as is using maven-surefire-plugin and/or maven-failsafe-plugin, Clover configuration may vary a little. See:
Get sources from Bitbucket: https://bitbucket.org/atlassian/maven-clover2-plugin, next go to src/it/webapp.
It' a simple web application with two servlets named MyServlet and RemoteServlet and a one JSP page. Maven during integration test phase runs unit test which calls servlets locally (by instantiating them) or remotely (in container).
A project build has been configured with a distributed coverage feature in such way that the "Server" (i.e. the JVM where JUnits are launched) will wait until at least one "Client" (i.e. the JVM where business code is executed; in our case inside a Tomcat container) connects to it. Because of fact that our servlet classes will not be loaded by Tomcat class loader until first HTTP request comes, an extra MyServletContextListener class was created. This class does virtually nothing, but due to fact that it's being loaded by class loader during application deployment, the Clover initialization code bundled into this class will run and connect to "Server" on a specified port. As soon as connection is established, "Server" will start execution of unit tests.