Testing with servlet engines

Last update : May 2 2001

Home
  • Jakarta Commons


  • About
  • News
  • Features
  • Goals
  • Changes
  • Todo
  • Contributors
  • Contributing
  • License


  • Downloads
  • Downloads


  • User Guides
  • Architecture
  • Installation
  • Installing Ant
  • Installing Sample
  • Configuration
  • Writing Test Case
  • Servlet Sample
  • Ant integration
  • Servlet Engines
  • API Reference


  • Support
  • CVS
  • Bug database
  • Mailing lists
  • FAQ


  • How to run Cactus tests in your servlet engine

    There are 2 parts in Cactus :

    • The Server part : It must contain the following elements :
      • the classes you want to test,
      • your Cactus test classes,
      • the Cactus jar,
      • the JUnit jar,
    • The Client part : It must contain the following elements :
      • your Cactus test classes,
      • the Cactus jar,
      • the Servlet API jar. This is needed because the ServletTestCase and JspTestCase classes use server objects.
      • the cactus.properties Cactus configuration file,
      • the JUnit jar,

    The Server part is usually packaged as a war file that you put in your Servlet engine webapps directory.

    On the client side you simply need to put the above-mentionned classes in your CLASSPATH (don't forget to put the cactus.properties file in your CLASSPATH). You start running the tests by starting a JUnit runner (either the gui one or the text one).


    Automating tests with your servlet engine and Ant

    The strategy for automating the unit tests with Ant is made up of the following steps :

    • Step 1 : set up your servlet engine needed configuration files in your out/ directory (see the Ant tutorial for the directory layout),
    • Step 2 : package your tests as a .war file and copy this war at a location in your out/ directory where you servlet engine will find it,
    • Step 3 : start your servlet engine in another thread and wait for it to be started (by trying to open an HTTP connection on a test URL),
    • Step 4 : run the JUnit test runner on your test classes,
    • Step 5 : stop the running servlet engine

    The following targets need to be defined for performing these steps :

    Target name   Description   Type  
    prepare_tests_<servlet engine name>   Prepare the servlet engine needed configuration files   Internal  
    testwar   Generate the test .war   Internal  
    start_<servlet engine name>   Starts the servlet engine   Internal  
    tests   Start the JUnit test runner on the Cactus test classes   Internal  
    stop_<servlet engine name>   Stops the servlet engine   Internal  
    tests_<servlet engine name>   Run the tests for that servlet engine   External  


    Supported servlet engines

    Cactus will work with any servlet engine that supports Servlet API 2.2 and above. The Cactus sample application provides Ant build scripts to automate running the tests for the following servlet engines :

    • Tomcat 3.2 (script for Servlet API 2.2)
    • Tomcat 4.0 (script for Servlet API 4.0)
    • Resin 1.2.x (script for Servlet API 2.2)
    • Resin 1.3.x (script for Servlet API 2.3)
    • Orion 1.4.x (script for Servlet API 2.2)
    • WebLogic 5.1 (script for Servlet API 2.2)

    Step 1 : 'prepare_tests_<servlet engine name>' target

    This step is very dependent on the servlet engine. Basically it consists in creating the needed directory structure in the out/ directory and copy the configuration files located in conf/test. See the tutorial for your specific servlet engine.

    We also check here if the home directory of the servlet engine has been specified. If not, then the tests for that servlet engine are not run.

    It will look like (example for Resin) :

        <!-- 
           ========================================================================
             Display a warning message if the needed servlet engine home property
             is not set
           ========================================================================
        -->
        <target name="check_tests_resin_12" depends="testwar" unless="resin.home.12">
    
            <echo message=""/>
            <echo message="*********************************************************"/>
            <echo message="WARNING : The 'resin.home.12' property has not been set."/>
            <echo message="          No test will be run on that servlet engine."/>
            <echo message="*********************************************************"/>
            <echo message=""/>
    
        </target>
    
        <!-- 
           ========================================================================
             Prepare directories and variables for running the tests
           ========================================================================
        -->
        <target name="prepare_tests_resin_12" depends="check_tests_resin_12" if="resin.home.12">
    
            <echo message="resin.home.12 = ${resin.home.12}"/>
    
            <property name="out.resin12.dir" value="${out.test.dir}/resin12"/>
            <property name="conf.resin12.dir" value="${conf.test.dir}/resin12"/>
    
            <mkdir dir="${out.resin12.dir}"/>
    
            <!-- Copy resin configuration files -->
            <copy file="${conf.resin12.dir}/resin.conf" tofile="${out.resin12.dir}/resin.conf"/>
    
            <!-- Create the war file -->
            <copy file="${out.test.dir}/test.war" tofile="${out.resin12.dir}/test.war"/>
    
        </target>
    

    Step 2 : 'testwar' target

    Generate the war file containing classes to test and test classes.

        <!-- 
           ========================================================================
             Create a test war file that includes the sample application unit tests
           ========================================================================
        -->
        <target name="testwar" depends="compile">
    
            <!-- Gather libraries -->
            <copy tofile="${out.lib.dir}/junit.jar" file="${junit.jar}"/>
            <copy tofile="${out.lib.dir}/cactus-22.jar" file="${cactus.jar}"/>
    
            <!-- Make sure the directory for the war exist -->
            <mkdir dir="${out.test.dir}"/>
    
            <!-- Create the war file -->
            <war warfile="${out.test.dir}/test.war"
                 webxml="${conf.test.dir}/web.xml">
    
                <classes dir="${out.classes.dir}">
                    <exclude name="cactus.properties"/>
                </classes>
    
                <!-- We need to copy the Cactus and JUnit jars in the war. This is
                     because if we just put these jars in the global classpath for
                     the Servlet engine, the Cactus jar might not be able to load
                     the test case class as it loadable only by the war classloader
                     -->
                <lib dir="${out.lib.dir}">
                    <include name="junit.jar"/>
                    <include name="cactus-22.jar"/>
                </lib>
    
                <fileset dir="${web.dir}"/>
     
           </war>
    
        </target>
    

    The web.xml need to contain the correct mapping for the Cactus Redirector servlet and Redirector JSP. See the installation tutorial.


    Step 3 : 'start_<servlet engine name>' target

    Again, this step depends on the servlet engine. The usual way to start the server is to use the Ant java task. See the tutorial for your specific servlet engine.

    Example (for Tomcat 3.2) :

        <!-- 
           ========================================================================
             Start Tomcat 3.2
           ========================================================================
        -->
        <target name="start_tomcat_32">
    
            <java classname="org.apache.tomcat.startup.Tomcat" fork="yes">
                <arg value="-config"/>
                <arg value="${out.tomcat32.dir}/conf/server.xml"/>
                <classpath>            
                    <pathelement location="${java.home}/../lib/tools.jar"/>
                    <fileset dir="${tomcat.home.32}/lib">
                        <include name="*.jar"/>
                    </fileset>
                </classpath>
            </java>
    
        </target>
    

    Step 4 : 'tests' target

    Starts the JUnit tests :

        <!-- 
           ========================================================================
             Run the client JUnit test cases. This target should not be called
             directly. It must be called by a test_XXX target (where XXX is the
             name of the server - see included xml file for different servers)
           ========================================================================
        -->
        <target name="tests">
    
            <junit printsummary="yes" haltonfailure="yes" haltonerror="yes" fork="yes">
    
                <classpath>
                    <pathelement path="${java.class.path}"/>
                    <pathelement location="${servlet.jar}"/>
                    <pathelement location="${cactus.jar}"/>
                    <pathelement location="${out.classes.dir}"/>
                </classpath>
    
                <formatter type="plain" usefile="false"/>
    
                <!-- Define tests here -->
                <test name="cactus.sample.TestSampleServlet"/>
                <test name="cactus.sample.TestSampleServletConfig"/>
    
            </junit>
    
        </target>
    

    Step 5 : 'stop_<servlet engine name>' target

    Again, this step depends on the servlet engine. The usual way to stop the server is to use the Ant java task. See the tutorial for your specific servlet engine.

    Example (for Tomcat 3.2) :

        <!-- 
           ========================================================================
             Stop Tomcat 3.2
           ========================================================================
        -->
        <target name="stop_tomcat_32">
    
            <java classname="org.apache.tomcat.startup.Tomcat" fork="yes">
                <jvmarg value="-Dtomcat.home=${tomcat.home.32}"/>
                <arg value="-stop"/>
                <classpath>            
                    <pathelement location="${java.home}/../lib/tools.jar"/>
                    <fileset dir="${tomcat.home.32}/lib">
                        <include name="*.jar"/>
                    </fileset>
                </classpath>
            </java>
    
        </target>
    

    'tests_<servlet engine name>' target

    This is the target that is called externally for starting the tests for a given servlet engine. It will call the start_<servlet engine name> target in another thread, wait for the servlet engine to be started (by continously trying to connect to a URL), run the tests by calling the tests target and then stop the servlet engine by calling the stop_<servlet engine name> target. It will also depend (in the Ant sense) on the prepare_tests_<servlet engine name> and testwar targets to prepare the test environment.

    Cactus provides a custom Ant task (named runservertests hereafter) to do this. This task is located in the cactus-ant.jar file. Here is an example of using this task for running the tests in Tomcat :

        <!-- 
           ========================================================================
             Run Tomcat 3.2 tests
           ========================================================================
        -->
        <target name="tests_tomcat_32" depends="prepare_tests_tomcat_32" if="tomcat.home.32">
    
            <!-- Start the servlet engine, wait for it to be started, run the
                 unit tests, stop the servlet engine, wait for it to be stopped.
                 The servlet engine is stopped if the tests fail for any reason -->
    
            <runservertests testURL="http://localhost:8080"
                startTarget="start_tomcat_32"
                stopTarget="stop_tomcat_32"
                testTarget="tests"/>
    
        </target>
    




    Copyright © 2000-2001 The Apache Software Foundation. All Rights Reserved.