Thursday, March 26, 2015

Integration Testing with SoapUI, Maven, Cargo, JaCoCo

Integration Testing RESTful Java Application

As a part of our Continous Delivery plan we wanted to have integration tests exercise our java code served.  The choosen means of integration testing was SoapUI which provides a advanced gui for setting up requests from wadl and generating tests from that.  Our goal was to have maven run soapui tests during the "integration-test" phase.  A code coverage report will help establish the quality of the testing beyond just know that X number tests were executed.



Maven

Using maven all these tools can be integrated to run right after build and succeed or fail the deployment/installation.  This is a very important part of the Continuous Delivery plan incorporating a fail-fast technique so broken code doesn't get past on to roll-outs.  Individual developers can also check their changed prior to check-in.

SoapUI

SoapUI was select as the tool for integration tests because is was useable by more then the developers in the organization.  The tests could be ported and expanded from development to QA and more widely used throughout the organization.  Also the required inputs would be documented by development because they would be in the test. 
<plugin>
                <groupId>com.smartbear.soapui</groupId>
                <artifactId>soapui-pro-maven-plugin</artifactId>
                <version>5.1.2</version>
                <configuration>
                    <projectFile>${basedir}/src/test/soapui/soapui-test.xml</projectFile>
                    <outputFolder>${basedir}/target/soapui-reports/</outputFolder>
                    <junitReport>true</junitReport>
                    <endpoint>http://localhost:9091</endpoint>
                    <skip>${skipITs}</skip>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.reflections</groupId>
                        <artifactId>reflections</artifactId>
                        <version>0.9.9-RC1</version>
                    </dependency>
                    <dependency>
                        <groupId>org.apache.poi</groupId>
                        <artifactId>poi-ooxml</artifactId>
                        <version>3.10-FINAL</version>
                        <exclusions>
                            <exclusion>
                                <groupId>org.apache.xmlbeans</groupId>
                                <artifactId>xmlbeans</artifactId>
                            </exclusion>
                        </exclusions>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>test</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

JaCoCo Javaagent http://www.eclemma.org/jacoco/

Jacoco monitors the JVM and analyses the code coverage of the tests.  One thing to note because new frameworks like spring proxy classes during runtime code jacoco can't follow the code coverage into proxy classes because classid get confused.  See link

<plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.7.2.201409121644</version>
                <configuration>
                    <destFile>${jacoco.reportPath}</destFile>
                    <dataFile>${jacoco.reportPath}</dataFile>
                    <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
                    <classDumpDir>${project.reporting.outputDirectory}/jacoco-it/classes</classDumpDir>
                    <skip>${skipITs}</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>jacoco-agent</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <destFile>${jacoco.reportPath}</destFile>
                            <propertyName>jacoco.agent.itArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>jacoco-report</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>dump</goal>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Cargo (Tomcat 7)

I had to use cargo over the maven-tomcat7 plugin because cargo allows you to inject the jacoco java agent.
<plugin>
                <groupId>org.codehaus.cargo</groupId>
                <artifactId>cargo-maven2-plugin</artifactId>
                <version>1.4.11</version>
                <configuration>
                    <skip>${skipITs}</skip>
                    <container>
                        <containerId>tomcat7x</containerId>
                        <zipUrlInstaller>
                            <url>http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.59/bin/apache-tomcat-7.0.59.zip</url>
                            <downloadDir>${project.build.directory}/downloads</downloadDir>
                            <extractDir>${project.build.directory}/extracts</extractDir>
                        </zipUrlInstaller>
                        <dependencies>
                            <dependency>
                                <groupId>oracle</groupId>
                                <artifactId>ojdbc6</artifactId>
                            </dependency>
                        </dependencies>
                    </container>
                    <configuration>
                        <home>${project.build.directory}/catalina-base</home>
                        <properties>
                            <cargo.jvmargs>${jacoco.agent.itArgLine},output=tcpserver,port=6300 -Drunmode=TEST</cargo.jvmargs>
                            <cargo.servlet.port>9091</cargo.servlet.port>
                            <cargo.tomcat.ajp.port>9100</cargo.tomcat.ajp.port>
                        </properties>
                        <configfiles>
                            <configfile>
                                <file>${basedir}/src/test/conf/context.xml</file>
                                <todir>conf/Catalina/localhost/</todir>
                                <tofile>context.xml.default</tofile>
                            </configfile>
                        </configfiles>
                    </configuration>
                </configuration>
                <executions>
                    <execution>
                        <id>start-tomcat</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>start</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>stop-tomcat</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>


No comments: