|
|
@@ -0,0 +1,312 @@ |
|
|
|
|
|
|
|
|
|
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
|
|
|
<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> |
|
|
|
</ul> |
|
|
|
</li> |
|
|
|
</ul> |
|
|
|
</div> |
|
|
|
<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="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, intializing 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 only a single implementation |
|
|
|
<code><plainlistener></code> modelled after the "plain" |
|
|
|
JUnit listener is bundeled 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, if if that causes an error --> |
|
|
|
<target name="tearDown"> |
|
|
|
<delete file="${foo}" quiet="true"/> |
|
|
|
</target> |
|
|
|
|
|
|
|
<!-- the actual test case --> |
|
|
|
<target name="testTouchCreatesFile"> |
|
|
|
<au:assertFileDoesntExist name="${foo}"/> |
|
|
|
<touch file="${foo}"/> |
|
|
|
<au:assertFileExists name="${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"> |
|
|
|
</pre> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<p class="copyright"> |
|
|
|
Copyright © 2000-2006 The Apache Software Foundation. All rights reserved. |
|
|
|
<script type="text/javascript" language="JavaScript"><!-- |
|
|
|
document.write(" - "+"Last Published: " + document.lastModified); |
|
|
|
// --> |
|
|
|
</script> |
|
|
|
</p> |
|
|
|
</body> |
|
|
|
</html> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|