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 4

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.

Group Targets Together
Create a new target that groups together the three targets you just created. The new target will be called "build-unpacked", and it is very short. Enter the following code snippet after the "compile-classes" target:

  <target name="build-unpacked"
          depends="init, create-unpacked-layout-dirs, copy-unprocessed-files, compile-classes"/>

The target is empty. It just invokes the init target to initialize property settings and the three other targets you previously created. You now have the ability to build the entire application and lay out the files in the structure mandated by the WAR standard.

The obvious next step is to turn the unpacked layout into a WAR before deploying the WAR to Tomcat. The following build.xml snippet creates a directory in which to place the WAR file:

  <target name="create-deploy-dir" depends="init">
    <mkdir dir="${build.dir}/deploy"/>

You should enter the "create-deploy-dir" target right after the "build-unpacked" target you just created. Now you have the unpacked layout of files and a place to store the WAR file.

The next step is to create the WAR file. WAR files must adhere to a defined layout. Put the following snippet of XML code in build.xml right after the "create-deploy-dir" target:

  <target name="package-war"
          depends="init, build-unpacked, create-deploy-dir"
          description="Build all the files and package them into a WAR file">
    <war warfile="${build.dir}/deploy/${war.base.name}.war"
      <webinf dir="${build.dir}/unpacked-layout/WEB-INF">
        <include name="**"/>
        <exclude name="web.xml"/>
        <exclude name="classes/**"/>
        <exclude name="lib/**"/>
      <classes dir="${build.dir}/unpacked-layout/WEB-INF/classes">
        <include name="**"/>
      <lib dir="${build.dir}/unpacked-layout/WEB-INF/lib">
        <include name="**"/>
      <fileset dir="${build.dir}/unpacked-layout">
        <include name="**"/>
        <exclude name="WEB-INF/**"/>

The "package-war" target makes use of the "build-unpacked" target to create the unpacked layout and the "create-deploy-dir" target to create the directory for the WAR file. The "package-war" target itself has only one instruction: war, which creates a WAR file and specifies the location of the WEB-INF directory, the classes directory, the lib directory, and the unprocessed files such as JSPs. At this point you have the ability to generate a WAR file capable of being deployed by Tomcat.

The next step is to copy the file into the Tomcat deployment directory so that Tomcat can deploy the application. The following XML snippet copies the WAR file to the Tomcat deployment directory:

  <target name="copy-war" depends="package-war">
    <copy file="${build.dir}/deploy/${war.base.name}.war" todir="${deploy.dir}"/>

Enter the "copy-war" target right after the "package-war" target. To tie the "package-war" and "copy-war" targets together into a useful deploy function, create another target that simply calls the "package-war" target, followed by the "copy-war" target. Call that target "deploy". Type the following into the build.xml file following the "copy-war" target:

  <target name="deploy" depends="package-war, copy-war" description="Deploy application to Tomcat"/>

The "deploy" target doesn't contain any actual instructions. It merely calls other targets to perform work. You should also create an "undeploy" target so that you can undeploy an old version of the phonelist application before deploying a new version that results from changes you make to the code. Tomcat does not automatically delete the unpacked directory or the WAR archive when you shut it down. Furthermore, Tomcat does not detect changes to the WAR archive, so it does not automatically deploy new versions of an application when new WAR files are copied over old ones in the Tomcat deploy directory (except in the case of statically specified Tomcat applications in the server.xml configuration file). For both of these reasons, it is important to have an undeploy target in the Ant build.xml file. Add the following XML snippet after the "deploy" target:

  <target name="undeploy" depends="init" description="Undeploy the application from Tomcat">
    <delete dir="${deploy.dir}/${war.base.name}"/>
    <delete file="${deploy.dir}/${war.base.name}.war"/>

Because you now have functioning targets in your Ant build file, you should change the default target. Currently you have the following in your build.xml file:

<project name="Phone List Application" basedir=".">

You should change it to the following:

<project name="Phone List Application" default="package-war" basedir=".">

At this point, you have a functioning build file with the ability to compile and deploy the application with one simple command line. The automated build will be essential during the development process. Look at the build.xml file included in the example code (phonelist-example-files.tgz or ".tbz2" or ".zip") supplied with this article. The build.xml file is called build.xml.v1. It is essentially the same as the build.xml file you just created, but it has things in a different order that makes it easier to read and maintain. It also has comments that were omitted from the XML fragments in the step-by-step instructions you just followed.

You may choose to use the build.xml.v1 file as your base moving forward, but you do not have to. You will be adding XML code to the build.xml file in order to add tests. If you do choose to use it, be sure to rename it to build.xml after copying it to the ~/projects/phonelist directory.

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