blob: 8ff5679d422147fe9e3ce51a9d1b20c39cfcab25 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content="Apache Forrest" name="Generator">
<meta name="Forrest-version" content="0.8-dev">
<meta name="Forrest-skin-name" content="pelt">
<title>Writing Unit Tests</title>
<link type="text/css" href="../skin/basic.css" rel="stylesheet">
<link media="screen" type="text/css" href="../skin/screen.css" rel="stylesheet">
<link media="print" type="text/css" href="../skin/print.css" rel="stylesheet">
<link type="text/css" href="../skin/profile.css" rel="stylesheet">
<script src="../skin/getBlank.js" language="javascript" type="text/javascript"></script><script src="../skin/getMenu.js" language="javascript" type="text/javascript"></script><script src="../skin/fontsize.js" language="javascript" type="text/javascript"></script>
<link rel="shortcut icon" href="../favicon.ico">
</head>
<body onload="init()">
<script type="text/javascript">ndeSetTextSize();</script>
<div id="top">
<!--+
|breadtrail
+-->
<div class="breadtrail">
<a href="http://www.apache.org/">apache</a> &gt; <a href="http://lenya.apache.org/">lenya</a><script src="../skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
</div>
<!--+
|header
+-->
<div class="header">
<!--+
|start group logo
+-->
<div class="grouplogo">
<a href=""><img class="logoImage" alt="Lenya" src="../images/apache-lenya-light.png" title=""></a>
</div>
<!--+
|end group logo
+-->
<!--+
|start Project Logo
+-->
<div class="projectlogo">
<a href=""></a>
</div>
<!--+
|end Project Logo
+-->
<!--+
|start Search
+-->
<div class="searchbox">
<form action="http://www.google.com/search" method="get" class="roundtopsmall">
<input value="lenya.apache.org" name="sitesearch" type="hidden"><input onFocus="getBlank (this, 'Search the site with ');" size="25" name="q" id="query" type="text" value="Search the site with ">&nbsp;
<input name="Search" value="Search" type="submit">
</form>
</div>
<!--+
|end search
+-->
<!--+
|start Tabs
+-->
<ul id="tabs">
<li>
<a class="unselected" href="../index.html">Project</a>
</li>
<li class="current">
<a class="selected" href="../docs/index.html">Documentation</a>
</li>
<li>
<a class="unselected" href="../community/index.html">Community</a>
</li>
</ul>
<!--+
|end Tabs
+-->
</div>
</div>
<div id="main">
<div id="publishedStrip">
<!--+
|start Subtabs
+-->
<div id="level2tabs">
<a class="unselected" href="../docs/1_4/index.html">Version 1.4</a><a class="unselected" href="../docs/modules/index.html">Modules</a><a class="unselected" href="../docs/1_2_x/index.html">Version 1.2</a>
</div>
<!--+
|end Endtabs
+-->
<script type="text/javascript"><!--
document.write("Last Published: " + document.lastModified);
// --></script>
</div>
<!--+
|breadtrail
+-->
<div class="breadtrail">
&nbsp;
</div>
<!--+
|start Menu, mainarea
+-->
<!--+
|start Menu
+-->
<div id="menu">
<div onclick="SwitchMenu('menu_selected_1.1', '../skin/')" id="menu_selected_1.1Title" class="menutitle" style="background-image: url('../skin/images/chapter_open.gif');">Documentation</div>
<div id="menu_selected_1.1" class="selectedmenuitemgroup" style="display: block;">
<div class="menuitem">
<a href="../docs/index.html">Index</a>
</div>
<div class="menuitem">
<a href="../docs/coding-guidelines.html">Coding Guidelines</a>
</div>
<div class="menupage">
<div class="menupagetitle">Unit Tests</div>
<div class="menupageitemgroup">
<div class="menupageitem">
<a href="#Introduction">Introduction</a>
</div>
<div class="menupageitem">
<a href="#Organization">Organization</a>
</div>
<div class="menupageitem">
<a title="The Test Publication" href="#The+Test+Publication">The Test Publicatio...</a>
</div>
<div class="menupageitem">
<a title="The PublicationHelper" href="#The+PublicationHelper">The PublicationHelp...</a>
</div>
<div class="menupageitem">
<a title="A TestCase Skeleton" href="#A+TestCase+Skeleton">A TestCase Skeleton...</a>
</div>
<div class="menupageitem">
<a title="Debugging a Test" href="#Debugging+a+Test">Debugging a Test...</a>
</div>
<div class="menupageitem">
<a title="The Test Buildfile" href="#The+Test+Buildfile">The Test Buildfile...</a>
</div>
<div class="menupageitem">
<a title="Adding the Test to the Buildfile" href="#Adding+the+Test+to+the+Buildfile">Adding the Test to ...</a>
</div>
</div>
</div>
<div class="menuitem">
<a href="../docs/website-update.html">Website Update</a>
</div>
<div class="menuitem">
<a href="../docs/release.html">Release Management</a>
</div>
<div class="menuitem">
<a href="../docs/zone.html">Zone notes</a>
</div>
</div>
<div id="credit"></div>
<div id="roundbottom">
<img style="display: none" class="corner" height="15" width="15" alt="" src="../skin/images/rc-b-l-15-1body-2menu-3menu.png"></div>
<!--+
|alternative credits
+-->
<div id="credit2">
<a href="http://apachecon.com/"><img border="0" title="ApacheCon EU 2006" alt="ApacheCon EU 2006 - logo" src="http://www.eu.apachecon.com/konferenzen/apachecon06/images/header-left.gif" style="width: 150px;height: 50px;"></a>
</div>
</div>
<!--+
|end Menu
+-->
<!--+
|start content
+-->
<div id="content">
<div title="Portable Document Format" class="pdflink">
<a class="dida" href="unittests.pdf"><img alt="PDF -icon" src="../skin/images/pdfdoc.gif" class="skin"><br>
PDF</a>
</div>
<h1>Writing Unit Tests</h1>
<a name="N1000E"></a><a name="Introduction"></a>
<h2 class="h3">Introduction</h2>
<div class="section">
<p>Recommended resources</p>
<ul>
<li>
<a href="http://www.junit.org">JUnit homepage</a>
</li>
<li>
<a href="http://junit.sourceforge.net/doc/cookbook/cookbook.htm">JUnit Cookbook</a> (Eric Gamma, Kent Beck)</li>
<li>
<a href="http://junit.sourceforge.net/doc/cookstour/cookstour.htm">JUnit: A Cook's Tour</a> (Eric Gamma, Kent Beck)</li>
<li>
<a href="http://junit.sourceforge.net/doc/testinfected/testing.htm">JUnitTest Infected: Programmers Love Writing Tests</a>
</li>
</ul>
</div>
<a name="N10031"></a><a name="Organization"></a>
<h2 class="h3">Organization</h2>
<div class="section">
<ul>
<li>
<p> Put your test classes in <em>src/test</em>. </p>
</li>
<li>
<p> Add the ant task that executes your test to <em>src/targets/test-build.xml</em>. </p>
</li>
</ul>
</div>
<a name="N10049"></a><a name="The+Test+Publication"></a>
<h2 class="h3">The Test Publication</h2>
<div class="section">
<p>Most tests will need a publication in the install (servlet container) directory. To provide a predictable test publication, the clean <em>default</em> publication from the build directory is copied to the <em>test</em> publication in the installation directory. </p>
<p>In the test buildfile, the test publication is setup by the <em>test.pub.prepare</em> target. The directory {{${install.dir}/lenya/pubs/test}} is deleted (so that the files created by former tests are removed), and the default publication is copied to this directory. Add this target to the <em>depends</em> attribute of your test target if you need the test publication. </p>
</div>
<a name="N10061"></a><a name="The+PublicationHelper"></a>
<h2 class="h3">The PublicationHelper</h2>
<div class="section">
<p>To simplify the acces to a publication you can use the class <em>org.apache.lenya.cms.PublicationHelper</em>. It provides the following methods: </p>
<pre class="code">
/**
* Initializes the object with the first parameters from the command
* line arguments &lt;code&gt;args&lt;/code&gt;. The remainder of the array is returned.
* @param args The command line arguments of the test.
* @return The remainder of the arguments after the publication
* parameters are extracted.
*/
public static String[] extractPublicationArguments(String args[]);
/**
* Returns the publication.
* @return A publication object.
*/
public static Publication getPublication();
</pre>
<p>The <em>extractPublicationArguments(String[])</em> method extracts the first two strings from the <em>args</em> parameter. The first one is the servlet context path, the second is the publication ID. </p>
<p>To make use of the PublicationHelper, you have to call the <em>extractPublicationArguments(String[])</em> method in the <em>main(String())</em> method of your <em>TestCase</em> class. This initializes the PublicationHelper: </p>
<pre class="code">
public static void main(String[] args) {
// extract the arguments needed for setting up the publication
// only the remaining arguments are returned
args = PublicationHelper.extractPublicationArguments(args);
...
}
</pre>
</div>
<a name="N1008A"></a><a name="A+TestCase+Skeleton"></a>
<h2 class="h3">A TestCase Skeleton</h2>
<div class="section">
<pre class="code">
public class MyTest extends TestCase {
// static fields to store test parameters
private File configFile;
...
/** Constructor. */
public MyTest(String test) {
super(test);
}
/**
* The main program.
* The parameters are set from the command line arguments.
*
* @param args The command line arguments.
*/
public static void main(String[] args) {
args = PublicationHelper.extractPublicationArguments(args);
setConfigFile(args[0]);
TestRunner.run(getSuite());
}
/** Returns the test suite. */
public static Test getSuite() {
return new TestSuite(MyTest.class);
}
/** Tests whatever you want. */
public void testSomething() {
...
}
/** Sets a parameter value. */
protected static void setConfigFile(String fileName) {
assertNotNull(string);
File publicationDirectory
= PublicationHelper.getPublication().getDirectory();
configFile = new File(publicationDirectory, fileName);
assertTrue(configFile.exists());
}
/** Returns a parameter value. */
protected static File getConfigFile() {
return configFile;
}
}
</pre>
</div>
<a name="N10094"></a><a name="Debugging+a+Test"></a>
<h2 class="h3">Debugging a Test</h2>
<div class="section">
<p>For debugging, it might be desired to run the test from an API. In this case, the <em>main(String[])</em> method is never executed. </p>
<p>To provide the parameters, you can hardcode them as fallback in the TestCase.setup() method that is called before the test is invoked: </p>
<pre class="code">
/** @see junit.framework.TestCase#setUp() */
protected void setUp() throws Exception {
if (getConfigFile() == null) {
String args[] = {
"D:\\Development\\build\\tomcat-4.1.24\\webapps\\lenya",
"test"
};
PublicationHelper.extractPublicationArguments(args);
setConfigFile("config/something.xconf");
}
}
</pre>
</div>
<a name="N100A7"></a><a name="The+Test+Buildfile"></a>
<h2 class="h3">The Test Buildfile</h2>
<div class="section">
<p>The test buildfile is located at <em>src/targets/test-build.xml</em>. It contains the following common targets: </p>
<ul>
<li>
<p>
<strong>test</strong> - Runs all tests. </p>
</li>
<li>
<p>
<strong>tests.junit</strong> - Runs the JUnit tests. </p>
</li>
<li>
<p>
<strong>tests.anteater</strong> - Runs the Anteater tests. </p>
</li>
<li>
<p>
<strong>tests.prepare</strong> - Prepares the tests, e.g. compiles test classes. </p>
</li>
<li>
<p>
<strong>test.pub.prepare</strong> - Prepares the test publication. </p>
</li>
</ul>
</div>
<a name="N100DE"></a><a name="Adding+the+Test+to+the+Buildfile"></a>
<h2 class="h3">Adding the Test to the Buildfile</h2>
<div class="section">
<p>To add your test to the buildfile, you create a target called <em>test.&lt;name&gt;</em>. </p>
<p>If you use assertions (Java assertions, not the JUnit ones) in your test, it is important to enable them using the <em>-ea</em> or <em>-enableassertions</em> argument. </p>
<pre class="code">
&lt;target name="test.my" depends="test.pub.prepare"&gt;
&lt;!-- My Test --&gt;
&lt;java fork="yes" classname="org.apache.lenya.cms.mypackage.MyTest"&gt;
&lt;jvmarg value="-enableassertions"/&gt;
&lt;arg value="${install.dir}"/&gt; // PublicationHelper
&lt;arg value="test"/&gt; // PublicationHelper
&lt;arg value="config/something.xconf"/&gt; // MyTest
&lt;classpath refid="classpath"/&gt;
&lt;classpath&gt;
&lt;pathelement location="${build.test}" /&gt;
&lt;pathelement path="${build.root}/lenya/webapp/WEB-INF/classes" /&gt;
&lt;fileset dir="${build.root}/lenya/webapp/WEB-INF/lib"&gt;
&lt;include name="ant**.jar"/&gt;
&lt;/fileset&gt;
&lt;/classpath&gt;
&lt;/java&gt;
&lt;/target&gt;
</pre>
<p>Finally, you have to add the test to the <em>tests.junit</em> target: </p>
<pre class="code">
&lt;target name="tests.junit" depends="init, tests.prepare, ..., test.my"&gt;
</pre>
<p>Now you can run the tests: </p>
<pre class="code">
$LENYA_HOME &gt; build test
</pre>
<p>If you want to call your test independently, you have to call the preparation targets before: </p>
<pre class="code">
$LENYA_HOME &gt; build init
$LENYA_HOME &gt; build tests.prepare
$LENYA_HOME &gt; build test.my
</pre>
</div>
</div>
<!--+
|end content
+-->
<div class="clearboth">&nbsp;</div>
</div>
<div id="footer">
<!--+
|start bottomstrip
+-->
<div class="lastmodified">
<script type="text/javascript"><!--
document.write("Last Published: " + document.lastModified);
// --></script>
</div>
<div class="copyright">
Copyright &copy;
2002-2005 <a href="http://www.apache.org/licenses/LICENSE-2.0">The Apache Software Foundation.</a>
</div>
<div id="feedback">
Send feedback about the website to:
<a id="feedbackto" href="mailto:dev@lenya.apache.org?subject=Feedback%C2%A0for%C2%A0docs/unittests.html">dev@lenya.apache.org</a>
</div>
<!--+
|end bottomstrip
+-->
</div>
</body>
</html>