<?xml version="1.0"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at
  
       http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<document>
  <properties>
    <title>JellyUnit</title>
    <author email="jstrachan@apache.org">James Strachan</author>
  </properties>

  <body>
    <section name="JellyUnit"> 
      <p>
        JellyUnit is a Jelly based JUnit testing mechanism. 
        This allows Jelly scripts to be used to perform unit testing which can be particularly useful
        if you wish to test XML, XPath, SQL, HTTP, JMS or SOAP interactions.
      </p>
      <p>
        JellyUnit works by using the <a href="libs/junit/tags.html">JUnit library </a> in a Jelly script
        to create JUnit TestSuite and TestCase objects. 
        There are all the usual JUnit assertion tests available such as &lt;assert&gt; 
        &lt;assertEquals&gt; and &lt;fail&gt;. You can use both Jexl and XPath expressions in the 
        &lt;assert&gt; tag via either the <i>test</i> or the <i>xpath</i> attributes.
      </p>
      <p>
        Inside these test scripts you can use the full range of Jelly tags such as navigating over
        XML test data creating multiple test cases based on sample data, performing SQL operations, SOAP calls, 
        HTTP or JMS requests etc. 
      </p>
      <p>
        You can also use Ant FileSets and the &lt;fileScanner&gt; tag to iterate over collections of 
        Jelly scripts or XML data files and use this data to define new test cases.
      </p>
    </section>
    
    <section name="Examples"> 
      <p>
        There is a simple example JellyUnit script
        <a href="http://svn.apache.org/repos/asf/commons/proper/jelly/trunk/jelly-tags/jelly-tags/junit/src/test/org/apache/commons/jelly/tags/junit/suite.jelly">here</a>
      </p>
      <p>
        An example demonstrating the use of the <a href="libs/betwixt/tags.html">Betwixt</a> library is 
        <a href="http://svn.apache.org/repos/asf/commons/proper/jelly/trunk/jelly-tags/betwixt/src/test/org/apache/commons/jelly/betwixt/suite.jelly">here</a>
        along with a common shared test script
        <a href="http://svn.apache.org/repos/asf/commons/proper/jelly/trunk/jelly-tags/betwixt/src/test/org/apache/commons/jelly/betwixt/common.jelly">here</a>
      </p>
      <p>
          The <a href="libs/validate/tags.html">validate</a> library can be used to perform XML validation inside JellyUnit.
          For example there's an example JellyUnit script validating XML 
          <a href="http://svn.apache.org/repos/asf/commons/proper/jelly/trunk/jelly-tags/validate/src/test/org/apache/commons/jelly/tags/validate/suite.jelly">here</a>
      </p>
    </section>

    <section name="Mock Tags"> 
      <p>
        In unit testing scenarios its often useful to use 
        <a href="http://c2.com/cgi/wiki?MockObject">Mock Objects</a> to test application logic and stub the behaviour
        of other service
      </p>
      <p>
        JellyUnit supports a feature called <i>Mock Tags</i> which are very similar to Mock Objects. 
        Mock Tags were invented by by Joe Walnes.
      </p>
      <p>
        Essentially the technique is to mock, or stub the behaviour of Jelly tags so that they give the results that you expect
        from services.
        For example imagine you had a Jelly script with tags which worked with databases or web services.
        You could use mock tags to stub what the tags are meant to do, to test your script invokes them correctly
        without requiring the underlying services
      </p>
      <p>
        There's an and example of using Mock Tags via the <a href="libs/define/tags.html">define</a> library 
        <a href="http://svn.apache.org/repos/asf/commons/proper/jelly/trunk/jelly-tags/define/src/test/org/apache/commons/jelly/tags/mock/suite.jelly">here</a>
        which creates the mock tags, inside a JellyUnit test case and then invokes this example 
        <a href="http://svn.apache.org/repos/asf/commons/proper/jelly/trunk/jelly-tags/define/src/test/org/apache/commons/jelly/tags/mock/service.jelly">service</a>
        using the mock tags rather than the underlying SQL and web service tags.
        Running the same service from outside of the Mock Tags JellyUnit test case would use the real tag implementations.
      </p>
    </section>
    

    <section name="Integration with TestRunners"> 
      <p>
        To integrate cleanly inside JUnit TestRunner frameworks there is a helper class,
        <a href="libs/junit/apidocs/org/apache/commons/jelly/tags/junit/JellyTestSuite.html">JellyTestSuite</a>
        which you can derive from
        to produce a single Java class which has a static <i>suite()</i> method to create a TestSuite object 
        containing all the test cases created by the JellyUnit files.
        There is an 
        <a href="http://svn.apache.org/repos/asf/commons/proper/jelly/trunk/jelly-tags/junit/src/test/org/apache/commons/jelly/junit/TestJUnit.java">example</a>
        of this in action.
      </p>
      <p>So if you had a test suite defined in a jelly script <a>suite.jelly</a> in a package com.acme.foo
          then you could create a class, capable of being ran inside any JUnit test runner framework as follows
      </p>
<source>
package com.acme.foo;
      
import junit.framework.TestSuite;

import org.apache.commons.jelly.tags.junit.JellyTestSuite;

/** 
 * A helper class to run jelly test cases in a JUnit TestRunner
 */
public class TestFoo extends JellyTestSuite {

    public static TestSuite suite() throws Exception {
        return createTestSuite(TestFoo.class, "suite.jelly");        
    }
}
</source>
    </section>
  </body>
</document>

