|
Last update : August 25 2002
Doc for : v1.4
About
What is Cactus ?
News
Changes
Features/Status
Goals
Roadmap/Todo
Contributors
Contributing
Cactus Users
Tested on ...
License
Downloads
Downloads
Documentation
How it works ?
Getting Started
Mock vs Container
Javadocs
FAQ
Howto Guides
Classpath Howto
Config Howto
Migration Howto
TestCase Howto
Jsp Howto
Runner Howto
Security Howto
Ant Howto
HttpUnit Howto
Sample Howto
EJB Howto
IDE Howto
Tomcat Howto
JUnitEE Howto
Support
Bug database
Mailing list
Misc.
Why the name ?
Logo Challenge
Resources
Test Coverage
Stats
Developers
CVS
Coding Conventions
Build results
Release Checklist
|
Introduction |
This tutorial explains how to write a test case, using Cactus. There
are several types of test cases : test cases for writing servlet
unit tests, test cases for writing taglib unit tests and test cases
for writing filter unit tests. We will first cover the principles
which are generic to all test cases and then we will dive into
the details specific to each test case.
 |
In order to help writing test case we highly suggest to have a look
at the examples provided as part of the Cactus distribution. Also,
all the best practices for JUnit also applies to Cactus test cases
as they are in essence JUnit test cases.
|
|
General principles |
To write a test case, please follow the steps defined below.
Step 1 : Imports |
You need to include the following imports in your test class (
junit.framework.* is needed because Cactus uses JUnit
as the client side application for calling the tests) :
import org.apache.cactus.*;
import junit.framework.*;
|
|
Step 2 : Extend a Cactus TestCase class |
Now, we need to create a class (our test class) that extends one of
Cactus test cases, depending on what we are testing :
-
ServletTestCase : extend this class
for writing tests for unit testing code that uses Servlet API
objects (HttpServletRequest ,
HttpServletResponse , HttpSession ,
ServletConfig , ServletContext , ...),
like Servlets or any java classes which have methods that
manipulates Servlet API objects. For example :
public class TestSampleServlet extends ServletTestCase
{
|
-
JspTestCase : extend this class for
writing tests for unit testing code that uses JSP API objects
(PageContext , JspWriter , ...), like
Taglibs or any java classes which have methods that manipulates
JSP API objects. For example :
public class TestSampleTag extends JspTestCase
{
|
-
FilterTestCase : extend this class
for writing tests for unit testing code that uses Filter API
objects (FilterChain , FilterConfig ,
HttpServletRequest , HttpServletResponse ,
...), like Filters or any java classes which have methods that
manipulates Filter API objects. For example :
public class TestSampleFilter extends FilterTestCase
{
|
|
Step 3 : Standard JUnit methods |
As in a normal JUnit test case, define the following standard JUnit
methods :
-
A constructor with a single parameter (it is the test name),
-
(optional): A
main() method in which you start a JUnit
test runner if you want your test to be executable,
-
(optional): A
suite() method to list the tests that
should be executed by your test class (default is to include all
method starting with "test ").
For example :
public TestSampleServlet(String theName)
{
super(theName);
}
public static void main(String[] theArgs)
{
junit.swingui.TestRunner.main(new String[] {TestSampleServlet.class.getName()});
}
public static Test suite()
{
return new TestSuite(TestSampleServlet.class);
}
|
|
Step 4 (optional) : setUp() and tearDown() methods |
As in JUnit, you can define a setUp() and a
tearDown() methods. They are executed respectively
before and after each test case. However, whereas in JUnit they are
executed on the client side, in Cactus they are executed on the
server side. It means that you will be able to access the Cactus
implicit object (these are the objects from the API as described
in Step 2) within them. In other words, you'll be able to do
things such as putting a value in the HTTP Session prior to calling
the test cases, etc.
As in JUnit, the setUp() and tearDown()
methods are optional.
|
Step 5 : testXXX() methods |
As in JUnit, the main method for a test is the
testXXX() method. The difference being that these
methods are executed in the container with Cactus. Each XXX test
case must have a testXXX() method defined.
In your testXXX() methods you will :
-
instantiate the class to test (you can also factor this instance
out and define is as a class instance variable),
-
setup any server-side domain object (like putting a variable in
the Http session, ...). Indeed, the Cactus test case class that
you have extended in Step 2 has several instance variables (they
are the different API objects mentioned in Step 2) that it has
initialised with valid objects. Depending on the test case class
that you have extended these variables are
request
(of type HttpServletRequest ),
config (of type ServletConfig for
ServletTestCase or of type FilterConfig
for FilterTestCase ), ... (see the "Testcase Specific
Details" Step below),
-
call the method to test,
-
perform JUnit standard asserts (
asserts(..) ,
assertEquals(...) , fail(...) , ...) to
verify that the test was successful
For Example :
public void testXXX()
{
// Initialize class to test
SampleServlet servlet = new SampleServlet();
// Set a variable in session as the doSomething() method that we are testing need
// this variable to be present in the session (for example)
session.setAttribute("name", "value");
// Call the method to test, passing an HttpServletRequest object (for example)
String result = servlet.doSomething(request);
// Perform verification that test was successful
assertEquals("something", result);
assertEquals("otherValue", session.getAttribute("otherName"));
}
|
|
Step 6 (optional) : beginXXX() methods |
For each XXX test case, you can define a corresponding
beginXXX() method (optional). You will use it to
initialize HTTP related parameters (HTTP parameters, cookies,
HTTP headers, URL to simulate, ...). You will be able to retrieve
these values in your testXXX() by calling the different
API of HttpServletRequest (like
getQueryString() , getCookies() ,
getHeader() , ...).
The signature of the begin method is :
public void beginXXX(WebRequest theRequest)
{
[...]
}
|
where theRequest is the object (provided by Cactus)
that you use to set all the HTTP related parameters.
The full description of all the HTTP related parameters that you can
set can be found in the javadoc for the WebRequest
class. You should also check the examples provided as part of the
Cactus distribution.
The beginXXX() methods are executed on the client
side, prior to executing testXXX() on the server side
and thus, do not have access to any of the class variables that
represent API objects (their values are null )
|
Step 7 (optional) : endXXX() methods |
For each XXX test case, you can define a corresponding
endXXX() method. You will use this method to
verify the returned HTTP related parameters from your test case
(like the returned content of the HTTP response, any returned
cookies, returned HTTP headers, ...).
For versions of Cactus up to v1.1, the signature of the end
method is :
public void endXXX(HttpURLConnection theConnection)
{
[...]
}
|
... and some helper methods to extract the response content and
cookies were provided in the AssertUtils class
(see javadoc).
However, beginning with Cactus 1.2, this signature has been
deprecated. There are now 2 possible signatures for the end
method, depending on whether you need to perform sophisticated
checks on the content of what is returned or not. For complex
checking, we have integrated with the
HttpUnit
framework. See the
HttpUnit tutorial for the
end method signatures and a full description.
The endXXX() methods are executed on the client
side, after executing testXXX() on the server side
and thus, do not have access to any of the class variables that
represent API objects (their values are null )
|
|
TestCase specific details |
Before reading any of the following detailed tutorials,
make sure you have read the previous general principles.
|
|
|