Wednesday, April 9, 2014

Automated Arquillian Test with Managed Tomcat

I recent faces this issue. In my test code, I use JMockit for Mock and Arquillian to drive the server. In the beginning I used embedded tomcat for test. But there is one problem, Arquillian runs both Server(embedded Tomcat) and client code in the same JVM. If one class is mocked, it is mocked in both client and server. But I only want to mock at client side. I need to use Managed Tomcat for test. But  I do not want the hassle to manage the server. Moreover,  when code is downloaded by others, or tested in CI server, I want to the test to be run in an automatic fashion. To work towards this end, I automate the Tomcat download and configuration process.

First, use the maven-cargo plugin to download Tomcat automatically
    <!-- launch tomcat, deploy application before integration test -->
            <plugin>
                <groupId>org.codehaus.cargo</groupId>
                <artifactId>cargo-maven2-plugin</artifactId>
                <version>1.4.6</version>
                <executions>
                    <!-- install tomcat
                    So it could be used by arquillion managed
                     -->
                    <execution>
                        <id>install-container</id>
                        <phase>generate-test-resources</phase>
                        <goals>
                            <goal>install</goal>
                        </goals>
                    </execution>
                     <configuration>                  

  <!-- Container configuration -->
                    <container>
                        <containerId>tomcat7x</containerId>
                        <zipUrlInstaller>
                            <url>http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.52/bin/apache-tomcat-7.0.52.zip</url>
                            <downloadDir>${project.build.directory}</downloadDir>
                              <extractDir>${project.build.directory}</extractDir>
                        </zipUrlInstaller>
                    </container>
            </plugin>


Then configure the download tomcat so that it can be managed remotely by Arquillian
<!--  copy customized tomcat configuration -->
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <executions>
                  <execution>
                    <id>copy-tomcat-config</id>
                    <!-- here the phase you need -->
                    <phase>process-test-resources</phase>
                    <goals>
                      <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                      <outputDirectory>${basedir}/target/apache-tomcat-7.0.52/apache-tomcat-7.0.52/conf</outputDirectory>
                      <resources>         
                        <resource>
                          <directory>${basedir}/src/test/resources/tomcat7x/conf</directory>
                        </resource>
                      </resources>             
                    </configuration>           
                  </execution>
                </executions>
              </plugin>

Here you prepare the configuration under /src/test/resources/tomcat7x/conf. They will be copied to installed Tomcat by this plugin.

Prepare the arquillian configuration so it knows how to communicate with managed tomcat: src/test/resources/arquillian.xml
<arquillian xmlns="http://jboss.org/schema/arquillian"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://jboss.org/schema/arquillian
        http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
      <!--
    https://docs.jboss.org/author/display/ARQ/Tomcat+7.0+-+Managed
     -->
    <container qualifier="tomcat-managed" default="true">
        <configuration>
            <property name="startupTimeoutInSeconds">20</property>
            <!-- The port to connect -->
            <property name="bindHttpPort">8888</property>
            <!--  the port to connect -->
<!--             <property name="jmxPort">8089</property> -->
            <property name="catalinaHome">target/apache-tomcat-7.0.52/apache-tomcat-7.0.52</property>
            <property name="outputToConsole">true</property>
             <property name="user">tomcat</property>
            <property name="pass">manager</property>
             <property name="host">localhost</property>
        </configuration>
    </container>
</arquillian>

The name of this configuration is tomcat-managed here.
Finally Let maven-surefire to use this arquillian configuration
    <!-- Fire unit test -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>                        <arquillian.launch>tomcat-managed</arquillian.launch>
                        <arquillian>tomcat-managed</arquillian>
                    </systemProperties>
                </configuration>
            </plugin>

Do not forget let arqillian to launch your managed tomcat for you.
<profile>
            <id>tomcat-managed</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <dependencies>
              <dependency>
                <groupId>org.jboss.arquillian.container</groupId>
                  <artifactId>arquillian-tomcat-managed-7</artifactId>
                  <version>1.0.0.CR6</version>
                  <scope>test</scope>
              </dependency>
            </dependencies>
        </profile>    



1 comment:

  1. My Rank, the only portal which offers jee mains online practice test with unlimited chapter wise practice test along with ask your query and live chat options. The portal is also loaded with WhiteBoard (live online classes by IITian faculty)

    ReplyDelete