| <!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> > <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 "> |
| <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"> |
| |
| |
| </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 <code>args</code>. 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.<name></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"> |
| <target name="test.my" depends="test.pub.prepare"> |
| <!-- My Test --> |
| <java fork="yes" classname="org.apache.lenya.cms.mypackage.MyTest"> |
| <jvmarg value="-enableassertions"/> |
| |
| <arg value="${install.dir}"/> // PublicationHelper |
| <arg value="test"/> // PublicationHelper |
| <arg value="config/something.xconf"/> // MyTest |
| |
| <classpath refid="classpath"/> |
| |
| <classpath> |
| <pathelement location="${build.test}" /> |
| <pathelement path="${build.root}/lenya/webapp/WEB-INF/classes" /> |
| <fileset dir="${build.root}/lenya/webapp/WEB-INF/lib"> |
| <include name="ant**.jar"/> |
| </fileset> |
| |
| </classpath> |
| </java> |
| </target> |
| </pre> |
| <p>Finally, you have to add the test to the <em>tests.junit</em> target: </p> |
| <pre class="code"> |
| |
| <target name="tests.junit" depends="init, tests.prepare, ..., test.my"> |
| </pre> |
| <p>Now you can run the tests: </p> |
| <pre class="code"> |
| $LENYA_HOME > 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 > build init |
| $LENYA_HOME > build tests.prepare |
| $LENYA_HOME > build test.my |
| |
| </pre> |
| </div> |
| |
| </div> |
| <!--+ |
| |end content |
| +--> |
| <div class="clearboth"> </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 © |
| 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> |