| |
| |
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| <!-- |
| 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. |
| --> |
| <html lang="en"> |
| <!-- GENERATED FILE, DO NOT EDIT, EDIT THE XML FILE IN xdocs INSTEAD! --> |
| <head> |
| <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>Apache Ant - AntUnit</title> |
| <link type="text/css" href="../../page.css" rel="stylesheet"> |
| </head> |
| |
| <body> |
| <p class="navpath"> |
| <script src="../../breadcrumbs.js" language="JavaScript" type="text/javascript"></script> |
| </p> |
| |
| <div class="logobar"> |
| <table width="100%" border="0" cellspacing="0" cellpadding="0"> |
| <tr> |
| <td align="left"><img border="0" alt="Apache Ant site" src="../../images/group-logo.gif"></td> |
| <td align="center" width="100%"><img alt="Apache Ant logo" border="0" src="../../images/project-logo.gif"></td> |
| <td align="right"> |
| <form target="_blank" onsubmit="q.value = query.value + ' site:ant.apache.org'" action="http://www.google.com/search" method="get"> |
| <table summary="search" border="0" cellspacing="0" cellpadding="0" bgcolor="#4C6C8F"> |
| <tr> |
| <td colspan="3"><img height="10" width="1" alt="" src="../../images/spacer.gif"></td> |
| </tr> |
| <tr> |
| <td><img height="1" width="1" alt="" src="../../images/spacer.gif"></td> |
| <td nowrap="nowrap" class="searchcaption"> |
| <input name="q" type="hidden"> |
| <input size="15" id="query" type="text"> |
| <img height="1" width="5" alt="" src="../../images/spacer.gif"> |
| <input name="Search" value="Search" type="submit"> |
| <br> |
| the Apache Ant site |
| </td> |
| <td><img height="1" width="1" alt="" src="../../images/spacer.gif"></td> |
| </tr> |
| <tr> |
| <td><img alt="" border="0" height="10" width="9" src="../../images/search-left.gif"></td> |
| <td><img height="1" width="1" alt="" src="../../images/spacer.gif"></td> |
| <td><img alt="" border="0" height="10" width="9" src="../../images/search-right.gif"></td> |
| </tr> |
| </table> |
| </form> |
| </td> |
| </tr> |
| </table> |
| </div> |
| |
| <div class="tab"> |
| <table summary="tab bar" border="0" cellpadding="0" cellspacing="0"> |
| <tr> |
| <td width="5"><img alt="" height="8" width="8" src="../../images/spacer.gif"></td><td valign="bottom"> |
| <table summary="non selected tab" style="height: 1.4em" border="0" cellpadding="0" cellspacing="0"> |
| <tr> |
| <td valign="top" width="5" bgcolor="#B2C4E0"><img height="5" width="5" alt="" src="../../images/tab-left.gif"></td><td valign="middle" bgcolor="#B2C4E0"><a href="../../index.html"><font size="2" face="Arial, Helvetica, Sans-serif">Home</font></a></td><td valign="top" width="5" bgcolor="#B2C4E0"><img height="5" width="5" alt="" src="../../images/tab-right.gif"></td> |
| </tr> |
| </table> |
| </td> |
| <td width="8"><img alt="" height="5" width="8" src="../../images/spacer.gif"></td><td valign="bottom"> |
| <table summary="selected tab" style="height: 1.5em" border="0" cellpadding="0" cellspacing="0"> |
| <tr> |
| <td valign="top" width="5" bgcolor="#4C6C8F"><img height="5" width="5" alt="" src="../../images/tabSel-left.gif"></td><td valign="middle" bgcolor="#4C6C8F"><font color="#ffffff" size="2" face="Arial, Helvetica, Sans-serif"><b>Projects</b></font></td><td valign="top" width="5" bgcolor="#4C6C8F"><img height="5" width="5" alt="" src="../../images/tabSel-right.gif"></td> |
| </tr> |
| </table> |
| </td> |
| </tr> |
| </table> |
| </div> |
| |
| <div class="bluebar"></div> |
| |
| <div class="menucontainer"> |
| <div class="menu"> |
| <ul> |
| <li class="menuheader">Projects |
| <ul> |
| <li> |
| <a href="../../projects/index.html">Welcome</a> |
| </li> |
| </ul> |
| </li> |
| <li class="menuheader">Ant Libraries |
| <ul> |
| <li> |
| <a href="../../antlibs/index.html">Introduction</a> |
| </li> |
| <li> |
| <a href="../../antlibs/charter.html">Charter</a> |
| </li> |
| <li> |
| <a href="../../antlibs/proper.html">Ant Libraries</a> |
| </li> |
| <li> |
| <a href="../../antlibs/sandbox.html">Sandbox Ant Libraries</a> |
| </li> |
| <li> |
| <a href="http://ant.apache.org/antlibs/bindownload.cgi">Binary Distributions</a> |
| </li> |
| <li> |
| <a href="http://ant.apache.org/antlibs/srcdownload.cgi">Source Distributions</a> |
| </li> |
| </ul> |
| </li> |
| <li class="menuheader">Ivy |
| <ul> |
| <li> |
| <a href="../../projects/ivy.html">Introduction</a> |
| </li> |
| <li> |
| <a href="http://ant.apache.org/ivy/">Homepage</a> |
| </li> |
| <li> |
| <a href="http://ant.apache.org/ivy/download.cgi">Distributions</a> |
| </li> |
| <li> |
| <a href="http://wiki.apache.org/ivy/">Wiki</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </div> |
| <center> |
| <!--#include virtual="/ads/buttonbar.html" --> |
| </center> |
| <img style="float: left" height="10" width="10" border="0" alt="" src="../../images/menu-left.gif"> |
| <img style="float: right" height="10" width="10" border="0" alt="" src="../../images/menu-right.gif"> |
| </div> |
| <div class="lightbluebar"> </div> |
| <div class="main"> |
| <div class="content"> |
| <h1 class="title">AntUnit</h1> |
| <h3 class="section"> |
| <a name="AntUnit 1.0"></a> |
| AntUnit 1.0 |
| </h3> |
| <h3>January 8, 2007 - Apache AntUnit 1.0 Available</h3> |
| <p>Apache AntUnit 1.0 is now available for download as <a href="http://ant.apache.org/antlibs/bindownload.cgi">binary</a> |
| or <a href="http://ant.apache.org/antlibs/srcdownload.cgi">source</a> |
| release.</p> |
| <h3 class="section"> |
| <a name="Idea"></a> |
| Idea |
| </h3> |
| <p>Initially all tests for Ant tasks were written as individual |
| <a href="http://www.junit.org/">JUnit</a> test cases. Pretty |
| soon it was clear that most tests needed to perform common tasks |
| like reading a build file, initializing a project instance with |
| it and executing a target. At this point <a href="http://svn.apache.org/viewcvs.cgi/ant/core/trunk/src/testcases/org/apache/tools/ant/BuildFileTest.java">BuildFileTest</a> |
| was invented, a base class for almost all task test cases.</p> |
| <p>BuildFileTest works fine and in fact has been picked up by <a href="http://ant-contrib.sf.net/">the Ant-Contrib Project</a> |
| and others as well.</p> |
| <p>Over time a new pattern evolved, more and more tests only |
| executed a target and didn't check any effects. Instead that |
| target contained the assertions as a <code><fail></code> |
| task. This is an example taken from the build file for the |
| ANTLR task (using Ant 1.7 features):</p> |
| <pre class="code"> |
| <target name="test3" depends="setup"> |
| <antlr target="antlr.g" outputdirectory="${tmp.dir}"/> |
| <fail> |
| <condition> |
| <!-- to prove each of these files exists; |
| ANTLR >= 2.7.6 leaves behind new (.smap) files as well. --> |
| <resourcecount when="ne" count="5"> |
| <fileset dir="${tmp.dir}"> |
| <include name="CalcParserTokenTypes.txt" /> |
| <include name="CalcParserTokenTypes.java" /> |
| <include name="CalcLexer.java" /> |
| <include name="CalcParser.java" /> |
| <include name="CalcTreeWalker.java" /> |
| </fileset> |
| </resourcecount> |
| </condition> |
| </fail> |
| </target> |
| </pre> |
| <p>where the corresponding JUnit testcase has been reduced |
| to</p> |
| <pre class="code"> |
| ... |
| public class ANTLRTest extends BuildFileTest { |
| |
| private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/antlr/"; |
| |
| public ANTLRTest(String name) { |
| super(name); |
| } |
| |
| public void setUp() { |
| configureProject(TASKDEFS_DIR + "antlr.xml"); |
| } |
| |
| public void tearDown() { |
| executeTarget("cleanup"); |
| } |
| |
| public void test3() { |
| executeTarget("test3"); |
| } |
| ... |
| } |
| </pre> |
| <p>This approach has a couple of advantages, one of them is that |
| it is very easy to translate an example build file from a bug |
| report into a test case. If you ask a user for a testcase for a |
| given bug in Ant, he now doesn't need to understand JUnit or how |
| to fit a test into Ant's existing tests any more.</p> |
| <p>AntUnit takes this approach to testing even further, it |
| removes JUnit completely and it comes with a set of predefined |
| <code><assert></code> tasks in order to reuse common kind |
| of checks.</p> |
| <p>It turns out that AntUnit lends itself as a solution to other |
| problems as well. The assertions are an easy way to validate a |
| setup before even starting the build process, for example. |
| AntUnit could also be used for functional and integration tests |
| outside of the scope of Ant tasks (assert contents of databases |
| after running an application, assert contents of HTTP responses |
| ...). This is an area that will need more research.</p> |
| <h3 class="section"> |
| <a name="Concepts"></a> |
| Concepts |
| </h3> |
| <h4 class="subsection"> |
| <a name="antunit Task"></a> |
| antunit Task |
| </h4> |
| <p>The <antunit> task drives the tests much like |
| <junit> does for JUnit tests.</p> |
| <p>When called on a build file, the task will start a new Ant |
| project for that build file and scan for targets with names |
| that start with "test". For each such target it then will</p> |
| <ol> |
| <li>Execute the target named setUp, if there is one.</li> |
| <li>Execute the target itself - if this target depends on |
| other targets the normal Ant rules apply and the dependent |
| targets are executed first.</li> |
| <li>Execute the target names tearDown, if there is one.</li> |
| </ol> |
| <h4 class="subsection"> |
| <a name="Assertions"></a> |
| Assertions |
| </h4> |
| <p>The base task is <code><assertTrue></code>. It |
| accepts a single nested condition and throws a subclass of |
| BuildException named AssertionFailedException if that |
| condition evaluates to false.</p> |
| <p>This task could have been implemented using |
| <code><macrodef></code> and <code><fail></code>, |
| but in fact it is a "real" task so that it is possible to |
| throw a subclass of BuildException. The |
| <code><antunit></code> task catches this exception and |
| marks the target as failed, any other type of Exception |
| (including other BuildException) are test errors.</p> |
| <p>Together with <code><assertTrue></code> there are |
| many predefined assertions for common conditions, most of |
| these are only macros.</p> |
| <h4 class="subsection"> |
| <a name="Other Tasks"></a> |
| Other Tasks |
| </h4> |
| <p>The <code><logcapturer></code> captures all messages |
| that pass Ant's logging system and provides them via a |
| reference inside of the project. If you want to assert |
| certain log messages, you need to start this task (prior to |
| your target under test) and use the |
| <code><assertLogContains></code> assertion.</p> |
| <p><code><expectFailure></code> is a task container that |
| catches any BuildException thrown by tasks nested into it. If |
| no exception has been thrown it will cause a test failure (by |
| throwing an AssertionFailedException).</p> |
| <h4 class="subsection"> |
| <a name="AntUnitListener"></a> |
| AntUnitListener |
| </h4> |
| <p>Part of the library is the <code>AntUnitListener</code> |
| interface that can be used to record test results. The |
| <antunit> task accepts arbitrary many listeners and |
| relays test results to them.</p> |
| <p>Currently two implementations - |
| <code><plainlistener></code> and <code>xmllistener</code> |
| modelled after the "plain" and "xml" |
| JUnit listeners - are bundled with the library.</p> |
| <h3 class="section"> |
| <a name="Examples"></a> |
| Examples |
| </h3> |
| <p>This is a way to test that <code><touch></code> |
| actually creates a file if it doesn't exist:</p> |
| <pre class="code"> |
| <project xmlns:au="antlib:org.apache.ant.antunit"> |
| <!-- is called prior to the test --> |
| <target name="setUp"> |
| <property name="foo" value="foo"/> |
| </target> |
| |
| <!-- is called after the test, even if that caused an error --> |
| <target name="tearDown"> |
| <delete file="${foo}" quiet="true"/> |
| </target> |
| |
| <!-- the actual test case --> |
| <target name="testTouchCreatesFile"> |
| <au:assertFileDoesntExist file="${foo}"/> |
| <touch file="${foo}"/> |
| <au:assertFileExists file="${foo}"/> |
| </target> |
| </project> |
| </pre> |
| <p>When running a task like</p> |
| <pre class="code"> |
| <au:antunit> |
| <fileset dir="." includes="touch.xml"/> |
| <au:plainlistener/> |
| </au:antunit> |
| </pre> |
| <p>from a buildfile of its own you'll get a result that looks like</p> |
| <pre class="code"> |
| [au:antunit] Build File: /tmp/touch.xml |
| [au:antunit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.249 sec |
| [au:antunit] Target: testTouchCreatesFile took 0.183 sec |
| |
| BUILD SUCCESSFUL |
| Total time: 1 second |
| </pre> |
| |
| </div> |
| </div> |
| |
| <p class="copyright"> |
| <script type="text/javascript" language="JavaScript"><!-- |
| document.write(" - "+"Last Published: " + document.lastModified); |
| // --> |
| </script> |
| </p> |
| </body> |
| </html> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |