RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Build a Java Web App Using HttpUnit and the Test-driven Methodology, Part I : Page 3

The HttpUnit client API complements JUnit functionality to provide thorough Web testing capability. This first article of a two-part series breaks down how HttpUnit delivers these features and walks you through a step-by-step setup of a test-driven environment.

Define Targets for Your Web App
Next, define some Ant targets that actually perform actions. For a Web application, at minimum you should be able to perform the following two tasks:
  1. Clean the directory, wiping out any object files or copied files so that you can start fresh with just the source code
  2. Compile and deploy the application to the Web server (Tomcat in this case)

The first task you will define in build.xml is a target named "clean" that will clean out the directory tree of any object files or processed files so you can do a fresh build. The second task you will define in build.xml is a target named "deploy" that will compile all of the classes, package the classes together with other Web files and descriptors into a WAR file, and then deploy the WAR file to the Web server. In addition, you will define a third task called "package-war" that will compile all of the classes and package together the unprocessed Web files (JSPs, images, property files, etc.) and Java classes into a WAR file that can be deployed to the Tomcat deployment directory (normally called "webapps" in a standard Tomcat distribution). The "package-war" target merely makes visible and public the intermediate steps of compiling and packaging files together into a WAR file. The "deploy" target ends up calling the "package-war" target.

The "clean" target is fairly easy to code up. Place the following XML snippet directly after the </target> tag that closes the <target name="init"> element but before the closing </project> tag:

  <target name="clean" depends="init" description="Clean build directory tree">
    <delete dir="${build.dir}"/>

The "deploy" target is more complicated, so break it down into multiple steps. It needs to do the following:

  1. Compile the servlets and other Java classes
  2. Assemble compiled classes and unprocessed files (such as JSPs, images, style sheets, and XML deployment descriptors) into a WAR file
  3. Deploy the application by copying the WAR file to the Tomcat directory

Compiling the Java classes and then assembling the compiled Java classes and all the unprocessed files together into a WAR file can be grouped together logically into a "package-war" target. Users can invoke this target directly in Ant.

A good way to figure out which targets you should create is to work backwards from your goal. You want to deploy a WAR file to Tomcat, so that means you need the WAR file with all of the files in the application bundled up. The easiest way to create this WAR file is to zip up a directory tree with the layout of the files matching the layout of the intended WAR file. Remember that a WAR file is simply a ZIP file with specific rules on which files need to be present and where certain files should go in the directory tree. To create the directory tree with the unpacked layout and content of the files, follow these steps:

  1. Set up the directories so that you have a place to put files.
  2. Copy files that do not need processing over to the unpacked layout directory tree. This will include JSPs, XML descriptor files, images, and other MIME types.
  3. Compile classes such as servlets. The object code is saved directly in the unpacked layout directory tree.

To set up the directories, enter the following snippet into build.xml following the "clean" target you just entered:

  <target name="create-unpacked-layout-dirs" depends="init">
    <mkdir dir="${build.dir}/unpacked-layout"/>
    <mkdir dir="${build.dir}/unpacked-layout/WEB-INF"/>
    <mkdir dir="${build.dir}/unpacked-layout/WEB-INF/classes"/>
    <mkdir dir="${build.dir}/unpacked-layout/WEB-INF/lib"/>

All of the JSPs, images, style sheets, and other files not needing compilation go directly in the unpacked-layout directory. The XML descriptors go in unpacked-layout/WEB-INF. The Java class files go in unpacked-layout/WEB-INF/classes. The JAR files for your libraries go in unpacked-layout/WEB-INF/lib.

The next step is to copy files not needing compilation into the unpacked-layout tree. Type the following in build.xml after the "create-unpacked-layout-dirs" target above:

  <target name="copy-unprocessed-files" depends="init, create-unpacked-layout-dirs">
    <copy todir="${build.dir}/unpacked-layout">
      <fileset dir="${src.dir}/web">
        <include name="**"/>
    <copy todir="${build.dir}/unpacked-layout/WEB-INF">
      <fileset dir="${src.dir}/WEB-INF">
        <exclude name="classes/**"/>
        <include name="**"/>
      <fileset dir="${struts.install.dir}/lib">
        <include name="*.tld"/>
        <include name="*.xml"/>
    <copy todir="${build.dir}/unpacked-layout/WEB-INF">
      <fileset dir="${src.dir}/WEB-INF">
        <include name="classes/**/*.properties"/>
      <fileset dir="${src.dir}/WEB-INF">
        <include name="classes/**/*.xml"/>
    <copy todir="${build.dir}/unpacked-layout/WEB-INF/lib">
      <fileset dir="${struts.install.dir}/lib">
        <include name="*.jar"/>

The "copy-unprocessed-files" target above first copies Web files such as JSPs directly into unpacked-layout, then copies XML descriptors into unpacked-layout/WEB-INF. After that, it copies resource properties or other resource files into unpacked-layout/WEB-INF/classes, and then copies JAR files into unpacked-layout/WEB-INF/lib.

Now turn to the files requiring compilation. Add the following snippet of XML code to build.xml after the "copy-unprocessed-files" target above:

  <target name="compile-classes" depends="init, create-unpacked-layout-dirs">
    <javac destdir="${build.dir}/unpacked-layout/WEB-INF/classes"
      <src path="${src.dir}/WEB-INF/classes"/>
      <classpath path="${classpath}"/>

The "compile-classes" target compiles all the files from WEB-INF/classes in the source tree. Recall that the location of the source tree was specified in the "init" target you created. The location was placed in the "src.dir" global property. The compiler uses the classpath specified in the "init" target. The classpath was placed in the "classpath" global property. The compiled object files are placed in the unpacked-layout/WEB-INF/classes directory.

You have now achieved the desired three steps:

  1. Set up the directories for the unpacked layout
  2. Copied files that do not need processing over to the unpacked layout directory tree
  3. Compiled classes such as servlets and placed the object code in the unpacked layout directory tree

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date