Question

Having following Maven project structure:

-project1          <-- parent pom with two children.
|--module1         <-- web services
\--module1-itest   <-- integration tests written with TestNG

What we do today:

  • Run mvn sonar:sonar in module1, which shows code coverage from the Unit tests in Sonar's dashboard.
  • Run mvn jetty:run on module1, and immediately after that run mvn test on module1-itests to test it.

I know this is far from the ideal scenario... it's more like an intermediate step while we try to improve a legacy project with almost no tests at all...


My question is: what would be the best way to get the code coverage done by the execution of the integration tests in Sonar's dashboard of module1?

Initially, I'm inclined to move the code in module1-itest to module1, and run them using the Failsafe plugin and the well-documented integration with JaCoCo. In this way, Module1 will have a mix of JUnit unit tests and TestNG integration tests, each group to be run by Surefire and Failsafe, respectively, starting up a Jetty server in the pre-integration phase.

However, we have reasons to keep both projects separated, so I'm wondering:

  1. Is the approach above a good one?
  2. Is there any other recommended way we can use to keep both projects separated, but including the code coverage done by module1-itest in module1 Sonar's dashboard?

Thanks,

Was it helpful?

Solution

This is how we solved it:

Summary:

  • Service and Service-itest projects are two independent modules.
  • Service has unit tests which coverage is reported by Sonar.
  • Service-itests uses Cargo to load the service WAR and run the integration tests. The code coverage collected in this execution is reported one level above. In this way, the coverage for the ITests is collected and merged cross-module and reported at the parent project pom level. We also like this approach becasue it allows us to have different ITests projects (for example, one with Cargo loading the app and another using JBehave), and they can evolve independently.

In the parent pom:

    <modules>
            <module>service</module>
            <module></module>
            <module>service-itest</module>
        </modules>
    <!-- Sonar -->
            <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
            <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
            <!-- The destination file for the code coverage report has to be set to 
                the same value in the parent pom and in each module pom. Then JaCoCo will 
                add up information in the same report, so that, it will give the cross-module 
                code coverage. -->
            <sonar.jacoco.itReportPath>${project.basedir}/../target/jacoco-itests.exec</sonar.jacoco.itReportPath>
...
<build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>0.6.3.201306030806</version>
                </plugin>
            </plugins>
        </pluginManagement>
...
<plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <configuration>
                    <includes>
                        <include>our.project.packages.*</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <id>pre-test</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>post-test</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

And in the pom.xml file of the -itest project:

<plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <configuration>
                    <!-- The destination file for the code coverage report has to be set 
                        to the same value in the parent pom and in each module pom. Then JaCoCo will 
                        add up information in the same report, so that, it will give the cross-module 
                        code coverage. -->
                    <destFile>${project.basedir}/../target/jacoco-itests.exec</destFile>
                    <includes>
                        <include>our.packages.*</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <id>post-test</id>
                        <configuration>
                            <skip>true</skip>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.cargo</groupId>
                <artifactId>cargo-maven2-plugin</artifactId>
                <version>1.2.2</version>
                <configuration>
                    <skip>${cargo.skip}</skip>
                    <container>
                        <containerId>jetty7x</containerId>
                        <artifactInstaller>
                            <groupId>org.eclipse.jetty</groupId>
                            <artifactId>jetty-distribution</artifactId>
                            <version>7.6.12.v20130726</version>
                            <type>zip</type>
                        </artifactInstaller>
                    </container>
                    <configuration>
                        <type>standalone</type>
                        <properties>
                            <cargo.servlet.port>${jetty.port}</cargo.servlet.port>
                            <cargo.jvmargs>${argLine}</cargo.jvmargs>
                        </properties>
                        <deployables>
                            <deployable>
                                <artifactId>pam_filetask_manager_service</artifactId>
                                <groupId>${project.groupId}</groupId>
                                <type>war</type>
                                <pingURL>http://server:22000/ping</pingURL>
                                <properties>
                                </properties>
                            </deployable>
                        </deployables>
                    </configuration>
                </configuration>
                <executions>
                    <execution>
                        <id>start-server</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>install</goal>
                            <goal>start</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>stop-server</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top