cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Upayavira>
Subject Re: [RT] Unit testing and CocoonUnit
Date Thu, 06 Nov 2003 14:30:52 GMT
Upayavira wrote:

> Giacomo Pati wrote:
>> Upayavira wrote:
>>> Steve K wrote:
>>>> Upayavira --
>>>> - Jakarta Cactus ( -- This takes 
>>>> a similar approach by setting up a mock servlet environment to test 
>>>> your servlets in.  However, it seemed way to big and complicated to 
>>>> do what I thought would be very simple.  Also, I think there is a 
>>>> lot to be gained by unit testing at the pipeline level as you 
>>>> suggest, rather than treating Cocoon like just another servlet.
>>> I skimmed it too, but it didn't seem to fit.
>> Have you guys also looked at Anteater
>> My personal experience with HTTPUnit is that is somehow inflexible 
>> and way too programmatic, not very declarative as Anteater is.
> I've looked into Anteater now, and I'm starting to see how I could 
> make a Cocoon unit test tool with it.
> ...

I copied this email to Jeff Turner (who is part responsible for 
Anteater). He said that it was, in his opinion, pretty much dead, as it 
did what it set out to do, but needed more higher level functionality. 
He now uses jWebUnit, which extends HttpUnit.

So, how does this proposal read:

CocoonUnit extention to HttpUnit and jWebUnit
My original proposal was to use the CocoonBean to access Cocoon. 
However, hacking HttpUnit and then jWebUnit to use the new access method 
would be a real pain. So....

A new CocoonUnit class can be used alongside HttpUnit or jWebUnit. 
HttpUnit or jWebUnit continue to make their tests using HTTP to a 
servlet container.

public class MyXMLTestCase extends XMLTestCase {
   public MyXMLTestCase(String name) {
   public void testForEquality() throws Exception {
      CocoonUnit cocoon = new 

      WebConversation webConversation =  new WebConversation();
      WebRequest request = new 

      WebResponse response = webConversation.getResponse(request);

      String generatorXML = cocoon.getPipelineXML(1);
      String transformedXML = cocoon.getPipelineXML(2);

      assertXpathExists("//para[contains(.,'Cocoon')]", generatorXML);
      assertXpathNotExists("//para[contains(.,'Active Server Pages')]", 

      // further tests on the transformedXML

In this way, HttpUnit requires no changes - all instructions to the 
server are made through this CocoonUnit object.

Cocoon Servlet Changes
The cocoon servlet is extended with a single extra init parameter "test" 
which is set to either 'on' or 'off'. (This could equally be in 

When the cocoon.informServer() method is called, an HTTP post is sent to 
the server, encapsulating details of the stages for which XML must be 
gathered. A couple of extra matchers placed in a pipeline will use an 
extension of the StreamGenerator to write the contents of this XML into 
an object in the transient store.

When the webConversation.getResponse() is called, the server, if the 
test input parameter is set to on, looks to see if this object is 
present in the persistent store. If it is, it inserts transformers into 
the pipeline as required to gather XML. This XML is then stored in the 
transient store, and the normal response is sent back to the user.

When the cocoon.getPipelineXML(1) method is called, an HTTP request is 
sent to the server, and the server returns the relevant XML out of the 
transient store.

The only downside of this as I currently see it is that only one person 
must be testing a site at any one time, as they cannot share their 
transient store objects.

This is by far the easiest solution to implement that I've come up with 
so far. It is not the most elegant internally, but from the user's point 
of view should be relatively easy to understand.

What do you think?

Regards,. Upayavira

View raw message