Code Coverage in Confluence Server Plugins

We are working through adding code coverage to one of our Confluence plugins.

Our first attempt has been with OpenClover and it is proving problematic with our Integration Tests (Unit tests are generating code coverage quite happily)

Clover tests need to have access to classes in clover-runtime.jar to work correctly, but we do not want to add this as a compile dependency as it is only required for our integration tests. Our integration tests are using Arquillian.

We attempted to add clover-runtime.jar as a libArtifact, which copies the jar into WEB-INF/lib correctly, but does not seem to actually expose the classes that the plugin needs. The plugin won’t enable with a ClassDefNotFound error looking for com_atlassian_clover

This is complicated by the fact that confluence bundles an old version of clover-runtime.jar (3.4.1), which may be conflicting in some way?

Basically I have two questions:

  • How are other plugin developers measuring code coverage? Should I just take the easy road and get JaCoCo or another library?
  • Has anyone managed to get OpenClover working with a Confluence plugin with remote integration tests? If so, what am I missing?

Thanks in advance.

1 Like

If anyone can share how to deploy (i.e. via pom.xml or some arcane maven calls) the clover-runtime (for OpenClover) into a container started by atlassian SDK when running integration tests (we are looking to do this in Bamboo), so the plugin code can actually find it via OSGi class loaders - this will be great.

I have also been trying something similar in Jira so if anyone has actually done it and has some tips lets us know tks

Finally thought up a way to do it which works.

It’s not pretty - but the idea is to create a compile dependency on clover runtime only when measuring coverage - and to export com_atlassian_clover package for your integration tests to find.

We can now run coverage with:
atlas-mvn clean org.openclover:clover-maven-plugin:setup verify org.openclover:clover-maven-plugin:aggregate org.openclover:clover-maven-plugin:clover -Pcoverage

include a node in pom.xml like:

<profile>
        <id>coverage</id>
            <dependencies>
                <dependency>
                    <groupId>org.openclover</groupId>
                    <artifactId>clover-runtime</artifactId>
                    <version>4.3.1</version>
                    <scope>compile</scope>
                </dependency>
            </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.openclover</groupId>
                    <artifactId>clover-maven-plugin</artifactId>
                    <version>4.3.1</version>
                    <configuration>
                        <includesTestSourceRoots>true</includesTestSourceRoots>
                        <singleCloverDatabase>true</singleCloverDatabase>
                        <cloverDatabase>${project.basedir}/target/clover/clover.db</cloverDatabase>
                        <distributedCoverage/> <!--This allows coverage of our in container integration tests -->
                        <!-- This is a custom report descriptor which just ensures we get both surefire and failsafe test reports -->
                        <reportDescriptor>clover-report.xml</reportDescriptor>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>${failsafe.version}</version>
                    <configuration>
                        <reportsDirectory>${surefire.and.failsafe.report.dir}</reportsDirectory>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>${surefire.version}</version>
                    <configuration>
                        <reportsDirectory>${surefire.and.failsafe.report.dir}</reportsDirectory>
                        <forkMode>once</forkMode>
                        <systemProperties>
                            <property>
                                <name>clover.server</name>
                                <value>true</value>
                            </property>
                        </systemProperties>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>com.atlassian.maven.plugins</groupId>
                    <!-- or jira-maven-plugin etc. -->
                    <artifactId>confluence-maven-plugin</artifactId>
                    <version>${amps.version}</version>
                    <extensions>true</extensions>
                    <configuration>
                        <instructions>
                            <!--We need to export these for our integration tests-->
                            <Export-Package>
                               <!--Anything you would usually export from your plugin for integration tests would also go here -->
                                com_atlassian_clover;version="4.3.1"
                            </Export-Package>
                        </instructions>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>

And our custom clover-report.xml in the root directory of the project:

<project>
<!-- Initialize Clover -->
<clover-setup initString="target/clover/clover.db"/>
<target name="historical">
<!-- Empty as we're not interested in historical reports right now -->
</target>
<target name="current">
<clover-report>
    <current outfile="${output}" title="${title}">
        <format type="html"/>
        <!-- Declare naming convention in order to have test classes listed on the "Test" tab in HTML report -->
        <testsources dir="src/test">
            <!-- Use Maven-Failsafe-Plugin naming convention -->
            <include name="**/IT*.java"/>
            <include name="**/*IT.java"/>
            <include name="**/*ITCase.java"/>
            <!-- Use Maven-Surefire-Pugin naming convention -->
            <include name="**/Test*.java"/>
            <include name="**/*Test.java"/>
            <include name="**/*TestCase.java"/>
        </testsources>
        <!-- Tell Clover to get test results directory as defined in pom.xml. They will be listed on "Results" tab -->
        <testresults dir="target/test-reports" includes="TEST-*.xml"/>
    </current>
</clover-report>
</target>
</project>