blob: 842e01739e2281f82a1dfa02affe639fd334f5bb [file] [log] [blame]
<?xml version="1.0"?>
<!--
Copyright 2002,2004 The Apache Software Foundation.
Licensed 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://cvs.apache.org/viewcvs.cgi/jakarta-commons/jelly/jelly-tags/junit/src/test/org/apache/commons/jelly/tags/junit/suite.jelly?rev=HEAD">here</a>
</p>
<p>
An example demonstrating the use of the <a href="libs/betwixt/tags.html">Betwixt</a> library is
<a href="http://cvs.apache.org/viewcvs.cgi/jakarta-commons/jelly/jelly-tags/betwixt/src/test/org/apache/commons/jelly/betwixt/suite.jelly?rev=HEAD">here</a>
along with a common shared test script
<a href="http://cvs.apache.org/viewcvs.cgi/jakarta-commons/jelly/jelly-tags/betwixt/src/test/org/apache/commons/jelly/betwixt/common.jelly?rev=HEAD">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://cvs.apache.org/viewcvs/jakarta-commons/jelly/jelly-tags/validate/src/test/org/apache/commons/jelly/tags/validate/suite.jelly?rev=HEAD">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://cvs.apache.org/viewcvs.cgi/jakarta-commons/jelly/jelly-tags/define/src/test/org/apache/commons/jelly/tags/mock/suite.jelly?rev=HEAD">here</a>
which creates the mock tags, inside a JellyUnit test case and then invokes this example
<a href="http://cvs.apache.org/viewcvs.cgi/jakarta-commons/jelly/jelly-tags/define/src/test/org/apache/commons/jelly/tags/mock/service.jelly?rev=HEAD">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://cvs.apache.org/viewcvs.cgi/jakarta-commons/jelly/jelly-tags/junit/src/test/org/apache/commons/jelly/junit/TestJUnit.java?rev=HEAD">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>