Ant Integration
To execute these tests, the easiest way I have found is to integrate it with Ant. Cactus is set up with an ant execution that allows me to run these tests and to cancel a build if the tests fail. The first step in the ant build.xml is to define the cactus tasks:
<taskdef resource="cactus.tasks"> <classpath> <pathelement location="lib/cactus-1.6.1.jar"/> <pathelement location="lib/cactus-ant-1.6.1.jar"/> <pathelement location="lib/commons-httpclient-2.0.jar"/> <pathelement location="lib/commons-logging-1.0.4.jar"/> <pathelement location="lib/aspecctjrt-1.1.1.jar"/> </classpath> </taskdef>
After the tasks are defined, the task that executes the cactus tests is as follows:
<target name="test" depends="war"> <cactifywar destfile="test-cactus.war" srcfile="test.war"/> <delete file="*.cactus.log"/> <cactus haltonfailure="yes" showoutput="yes" printsummary="on" warfile="test-cactus.war"> <cactusproperty server="false" propertiesFile="conf/cactus.client.log4j.properties"/> <cactusproperty server="true" propertiesFile="conf/cactus.server.log4j.properties"/> <classpath refid="classpath"/> <containerset> <tomcat4x dir="${env.CATALINA_HOME}" output="tomcat.cactus.log"/> </containerset> <test name="com.dzrealms.example.servlet.ExampleCactusTest" outfile="cactus.output"> <formatter type="plain"/> </test> </cactus> <delete file="test-cactus.war"/> </target>
The first thing to do in this target is to "cactify" the war file produced in another portion of the build. This step adds additional libraries to the war file that allow cactus to "hook" into the application. Next, I delete any old log files to avoid confusion. The next step is the actual execution of the test. First, I am telling Cactus to halt if there are any errors in the tests, to show the output of the tests, and to print a summary when everything is done. Next, I configure a log4j properties file for both the client and server jvms. This file captures any logging output that is defined within the servlet or other objects during the testing.
The <containerset> tag tells Cactus what Servlet container to use for the test. Cactus uses any container you have installed and configured on your system. It is pre-setup to handle several of the most common containers.
NOTE
In this case I am using Tomcat, but I can just as easily use JBoss or Resin.
The final piece of information in the test is to tell Cactus which test class to execute. Within this tag, I can define how I want the output from the test to be formatted. This is helpful for automated testing and code compilation. In this example, I use a plain output.
After the test is complete, I delete the "cactified" war file so that it is not accidentally used or reused in the future.
The output from executing the test target from Ant should be similar to this:
test: [cactifywar] Analyzing war: /Users/mzarra/Development/Examples/test.war [cactifywar] Building war: /Users/mzarra/Development/Examples/test-cactus.war [cactus] ----------------------------------------------------------------- [cactus] Running tests against Tomcat 4.1.30 [cactus] ----------------------------------------------------------------- [cactus] Deleting 32 files from /tmp/cactus/tomcat4x [cactus] Deleted 16 directories from /tmp/cactus/tomcat4x [cactus] Running com.dzrealms.example.servlet.ExampleCactusTest [cactus] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.703 sec [delete] Deleting: /Users/mzarra/Development/Examples/test-cactus.war