[14982] | 1 | <!--
|
---|
| 2 | Licensed to the Apache Software Foundation (ASF) under one or more
|
---|
| 3 | contributor license agreements. See the NOTICE file distributed with
|
---|
| 4 | this work for additional information regarding copyright ownership.
|
---|
| 5 | The ASF licenses this file to You under the Apache License, Version 2.0
|
---|
| 6 | (the "License"); you may not use this file except in compliance with
|
---|
| 7 | the License. You may obtain a copy of the License at
|
---|
| 8 |
|
---|
| 9 | http://www.apache.org/licenses/LICENSE-2.0
|
---|
| 10 |
|
---|
| 11 | Unless required by applicable law or agreed to in writing, software
|
---|
| 12 | distributed under the License is distributed on an "AS IS" BASIS,
|
---|
| 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
| 14 | See the License for the specific language governing permissions and
|
---|
| 15 | limitations under the License.
|
---|
| 16 | -->
|
---|
| 17 | <html>
|
---|
| 18 | <head>
|
---|
| 19 | <title>Tutorial: Hello World with Ant</title>
|
---|
| 20 | <meta name="author" content="Jan Matï¿œne">
|
---|
| 21 | <link rel="stylesheet" type="text/css" href="stylesheets/style.css">
|
---|
| 22 | <style type="text/css">
|
---|
| 23 | <!--
|
---|
| 24 | .code { background: #EFEFEF; margin-top: }
|
---|
| 25 | .output { color: #FFFFFF; background: #837A67; }
|
---|
| 26 | -->
|
---|
| 27 | </style>
|
---|
| 28 | </head>
|
---|
| 29 | <body>
|
---|
| 30 | <h1>Tutorial: Hello World with Ant</h1>
|
---|
| 31 |
|
---|
| 32 | <p>This document provides a step by step tutorial for starting java programming with Ant.
|
---|
| 33 | It does <b>not</b> contain deeper knowledge about Java or Ant. This tutorial has the goal
|
---|
| 34 | to let you see, how to do the easiest steps in Ant.</p>
|
---|
| 35 |
|
---|
| 36 |
|
---|
| 37 |
|
---|
| 38 | <h2>Content</h2>
|
---|
| 39 | <p><ul>
|
---|
| 40 | <li><a href="#prepare">Preparing the project</a></li>
|
---|
| 41 | <li><a href="#four-steps">Enhance the build file</a></li>
|
---|
| 42 | <li><a href="#enhance">Enhance the build file</a></li>
|
---|
| 43 | <li><a href="#ext-libs">Using external libraries</a></li>
|
---|
| 44 | <li><a href="#resources">Resources</a></li>
|
---|
| 45 | </ul></p>
|
---|
| 46 |
|
---|
| 47 |
|
---|
| 48 | <a name="prepare"></a>
|
---|
| 49 | <h2>Preparing the project</h2>
|
---|
| 50 | <p>We want to separate the source from the generated files, so our java source files will
|
---|
| 51 | be in <tt>src</tt> folder. All generated files should be under <tt>build</tt>, and there
|
---|
| 52 | splitted into several subdirectories for the individual steps: <tt>classes</tt> for our compiled
|
---|
| 53 | files and <tt>jar</tt> for our own JAR-file.</p>
|
---|
| 54 | <p>We have to create only the <tt>src</tt> directory. (Because I am working on Windows, here is
|
---|
| 55 | the win-syntax - translate to your shell):</p>
|
---|
| 56 |
|
---|
| 57 | <pre class="code">
|
---|
| 58 | md src
|
---|
| 59 | </pre>
|
---|
| 60 |
|
---|
| 61 | <p>The following simple Java class just prints a fixed message out to STDOUT,
|
---|
| 62 | so just write this code into <tt>src\oata\HelloWorld.java</tt>.</p>
|
---|
| 63 |
|
---|
| 64 | <pre class="code">
|
---|
| 65 | package oata;
|
---|
| 66 |
|
---|
| 67 | public class HelloWorld {
|
---|
| 68 | public static void main(String[] args) {
|
---|
| 69 | System.out.println("Hello World");
|
---|
| 70 | }
|
---|
| 71 | }
|
---|
| 72 | </pre>
|
---|
| 73 |
|
---|
| 74 | <p>Now just try to compile and run that:
|
---|
| 75 | <pre class="code">
|
---|
| 76 | md build\classes
|
---|
| 77 | javac -sourcepath src -d build\classes src\oata\HelloWorld.java
|
---|
| 78 | java -cp build\classes oata.HelloWorld
|
---|
| 79 | </pre>
|
---|
| 80 | which will result in
|
---|
| 81 | <pre class="output">
|
---|
| 82 | Hello World
|
---|
| 83 | </pre>
|
---|
| 84 | </p>
|
---|
| 85 |
|
---|
| 86 | <p>Creating a jar-file is not very difficult. But creating a <i>startable</i> jar-file needs more steps: create a
|
---|
| 87 | manifest-file containing the start class, creating the target directory and archiving the files.</p>
|
---|
| 88 | <pre class="code">
|
---|
| 89 | echo Main-Class: oata.HelloWorld>myManifest
|
---|
| 90 | md build\jar
|
---|
| 91 | jar cfm build\jar\HelloWorld.jar myManifest -C build\classes .
|
---|
| 92 | java -jar build\jar\HelloWorld.jar
|
---|
| 93 | </pre>
|
---|
| 94 |
|
---|
| 95 | <p><b>Note:</b> Do not have blanks around the >-sign in the <tt>echo Main-Class</tt> instruction because it would
|
---|
| 96 | falsify it!</p>
|
---|
| 97 |
|
---|
| 98 |
|
---|
| 99 | <a name="four-steps"></a>
|
---|
| 100 | <h2>Four steps to a running application</h2>
|
---|
| 101 | <p>After finishing the java-only step we have to think about our build process. We <i>have</i> to compile our code, otherwise we couldn't
|
---|
| 102 | start the program. Oh - "start" - yes, we could provide a target for that. We <i>should</i> package our application.
|
---|
| 103 | Now it's only one class - but if you want to provide a download, no one would download several hundreds files ...
|
---|
| 104 | (think about a complex Swing GUI - so let us create a jar file. A startable jar file would be nice ... And it's a
|
---|
| 105 | good practise to have a "clean" target, which deletes all the generated stuff. Many failures could be solved just
|
---|
| 106 | by a "clean build".</p>
|
---|
| 107 |
|
---|
| 108 | <p>By default Ant uses <tt>build.xml</tt> as the name for a buildfile, so our <tt>.\build.xml</tt> would be:</p>
|
---|
| 109 | <pre class="code">
|
---|
| 110 | <project>
|
---|
| 111 |
|
---|
| 112 | <target name="clean">
|
---|
| 113 | <delete dir="build"/>
|
---|
| 114 | </target>
|
---|
| 115 |
|
---|
| 116 | <target name="compile">
|
---|
| 117 | <mkdir dir="build/classes"/>
|
---|
| 118 | <javac srcdir="src" destdir="build/classes"/>
|
---|
| 119 | </target>
|
---|
| 120 |
|
---|
| 121 | <target name="jar">
|
---|
| 122 | <mkdir dir="build/jar"/>
|
---|
| 123 | <jar destfile="build/jar/HelloWorld.jar" basedir="build/classes">
|
---|
| 124 | <manifest>
|
---|
| 125 | <attribute name="Main-Class" value="oata.HelloWorld"/>
|
---|
| 126 | </manifest>
|
---|
| 127 | </jar>
|
---|
| 128 | </target>
|
---|
| 129 |
|
---|
| 130 | <target name="run">
|
---|
| 131 | <java jar="build/jar/HelloWorld.jar" fork="true"/>
|
---|
| 132 | </target>
|
---|
| 133 |
|
---|
| 134 | </project>
|
---|
| 135 | </pre>
|
---|
| 136 |
|
---|
| 137 | <p>Now you can compile, package and run the application via</p>
|
---|
| 138 | <pre class="code">
|
---|
| 139 | ant compile
|
---|
| 140 | ant jar
|
---|
| 141 | ant run
|
---|
| 142 | </pre>
|
---|
| 143 | <p>Or shorter with</p>
|
---|
| 144 | <pre class="code">
|
---|
| 145 | ant compile jar run
|
---|
| 146 | </pre>
|
---|
| 147 |
|
---|
| 148 | <p>While having a look at the buildfile, we will see some similar steps between Ant and the java-only commands:
|
---|
| 149 | <table>
|
---|
| 150 | <tr>
|
---|
| 151 | <th>java-only</th>
|
---|
| 152 | <th>Ant</th>
|
---|
| 153 | </tr>
|
---|
| 154 | <tr>
|
---|
| 155 | <td valign="top"><pre class="code">
|
---|
| 156 | md build\classes
|
---|
| 157 | javac
|
---|
| 158 | -sourcepath src
|
---|
| 159 | -d build\classes
|
---|
| 160 | src\oata\HelloWorld.java
|
---|
| 161 | echo Main-Class: oata.HelloWorld>mf
|
---|
| 162 | md build\jar
|
---|
| 163 | jar cfm
|
---|
| 164 | build\jar\HelloWorld.jar
|
---|
| 165 | mf
|
---|
| 166 | -C build\classes
|
---|
| 167 | .
|
---|
| 168 |
|
---|
| 169 |
|
---|
| 170 |
|
---|
| 171 | java -jar build\jar\HelloWorld.jar
|
---|
| 172 | </pre></td>
|
---|
| 173 | <td valign="top"><pre class="code">
|
---|
| 174 | <mkdir dir="build/classes"/>
|
---|
| 175 | <javac
|
---|
| 176 | srcdir="src"
|
---|
| 177 | destdir="build/classes"/>
|
---|
| 178 | <i><!-- automatically detected --></i>
|
---|
| 179 | <i><!-- obsolete; done via manifest tag --></i>
|
---|
| 180 | <mkdir dir="build/jar"/>
|
---|
| 181 | <jar
|
---|
| 182 | destfile="build/jar/HelloWorld.jar"
|
---|
| 183 |
|
---|
| 184 | basedir="build/classes">
|
---|
| 185 | <manifest>
|
---|
| 186 | <attribute name="Main-Class" value="oata.HelloWorld"/>
|
---|
| 187 | </manifest>
|
---|
| 188 | </jar>
|
---|
| 189 | <java jar="build/jar/HelloWorld.jar" fork="true"/>
|
---|
| 190 | </pre></td>
|
---|
| 191 | </tr></table>
|
---|
| 192 | </p>
|
---|
| 193 |
|
---|
| 194 |
|
---|
| 195 |
|
---|
| 196 | <a name="enhance"></a>
|
---|
| 197 | <h2>Enhance the build file</h2>
|
---|
| 198 | <p>Now we have a working buildfile we could do some enhancements: many time you are referencing the
|
---|
| 199 | same directories, main-class and jar-name are hard coded, and while invocation you have to remember
|
---|
| 200 | the right order of build steps.</p>
|
---|
| 201 | <p>The first and second point would be addressed with <i>properties</i>, the third with a special property - an attribute
|
---|
| 202 | of the <project>-tag and the fourth problem can be solved using dependencies.</p>
|
---|
| 203 |
|
---|
| 204 |
|
---|
| 205 | <pre class="code">
|
---|
| 206 | <project name="HelloWorld" basedir="." default="main">
|
---|
| 207 |
|
---|
| 208 | <property name="src.dir" value="src"/>
|
---|
| 209 |
|
---|
| 210 | <property name="build.dir" value="build"/>
|
---|
| 211 | <property name="classes.dir" value="${build.dir}/classes"/>
|
---|
| 212 | <property name="jar.dir" value="${build.dir}/jar"/>
|
---|
| 213 |
|
---|
| 214 | <property name="main-class" value="oata.HelloWorld"/>
|
---|
| 215 |
|
---|
| 216 |
|
---|
| 217 |
|
---|
| 218 | <target name="clean">
|
---|
| 219 | <delete dir="${build.dir}"/>
|
---|
| 220 | </target>
|
---|
| 221 |
|
---|
| 222 | <target name="compile">
|
---|
| 223 | <mkdir dir="${classes.dir}"/>
|
---|
| 224 | <javac srcdir="${src.dir}" destdir="${classes.dir}"/>
|
---|
| 225 | </target>
|
---|
| 226 |
|
---|
| 227 | <target name="jar" depends="compile">
|
---|
| 228 | <mkdir dir="${jar.dir}"/>
|
---|
| 229 | <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
|
---|
| 230 | <manifest>
|
---|
| 231 | <attribute name="Main-Class" value="${main-class}"/>
|
---|
| 232 | </manifest>
|
---|
| 233 | </jar>
|
---|
| 234 | </target>
|
---|
| 235 |
|
---|
| 236 | <target name="run" depends="jar">
|
---|
| 237 | <java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/>
|
---|
| 238 | </target>
|
---|
| 239 |
|
---|
| 240 | <target name="clean-build" depends="clean,jar"/>
|
---|
| 241 |
|
---|
| 242 | <target name="main" depends="clean,run"/>
|
---|
| 243 |
|
---|
| 244 | </project>
|
---|
| 245 | </pre>
|
---|
| 246 |
|
---|
| 247 |
|
---|
| 248 | <p>Now it's easier, just do a <tt class="code">ant</tt> and you will get</p>
|
---|
| 249 | <pre class="output">
|
---|
| 250 | Buildfile: build.xml
|
---|
| 251 |
|
---|
| 252 | clean:
|
---|
| 253 |
|
---|
| 254 | compile:
|
---|
| 255 | [mkdir] Created dir: C:\...\build\classes
|
---|
| 256 | [javac] Compiling 1 source file to C:\...\build\classes
|
---|
| 257 |
|
---|
| 258 | jar:
|
---|
| 259 | [mkdir] Created dir: C:\...\build\jar
|
---|
| 260 | [jar] Building jar: C:\...\build\jar\HelloWorld.jar
|
---|
| 261 |
|
---|
| 262 | run:
|
---|
| 263 | [java] Hello World
|
---|
| 264 |
|
---|
| 265 | main:
|
---|
| 266 |
|
---|
| 267 | BUILD SUCCESSFUL
|
---|
| 268 | </pre>
|
---|
| 269 |
|
---|
| 270 |
|
---|
| 271 | <a name="ext-libs"></a>
|
---|
| 272 | <h2>Using external libraries</h2>
|
---|
| 273 | <p>Somehow told us not to use syso-statements. For log-Statements we should use a Logging-API - customizable on a high
|
---|
| 274 | degree (including switching off during usual life (= not development) execution). We use Log4J for that, because <ul>
|
---|
| 275 | <li>it is not part of the JDK (1.4+) and we want to show how to use external libs</li>
|
---|
| 276 | <li>it can run under JDK 1.2 (as Ant)</li>
|
---|
| 277 | <li>it's highly configurable</li>
|
---|
| 278 | <li>it's from Apache ;-)</li>
|
---|
| 279 | </ul></p>
|
---|
| 280 | <p>We store our external libraries in a new directory <tt>lib</tt>. Log4J can be
|
---|
| 281 | <a href="http://www.apache.org/dist/logging/log4j/1.2.13/logging-log4j-1.2.13.zip">downloaded [1]</a> from Logging's Homepage.
|
---|
| 282 | Create the <tt>lib</tt> directory and extract the log4j-1.2.9.jar into that lib-directory. After that we have to modify
|
---|
| 283 | our java source to use that library and our buildfile so that this library could be accessed during compilation and run.
|
---|
| 284 | </p>
|
---|
| 285 | <p>Working with Log4J is documented inside its manual. Here we use the <i>MyApp</i>-example from the
|
---|
| 286 | <a href="http://logging.apache.org/log4j/docs/manual.html">Short Manual [2]</a>. First we have to modify the java source to
|
---|
| 287 | use the logging framework:</p>
|
---|
| 288 |
|
---|
| 289 | <pre class="code">
|
---|
| 290 | package oata;
|
---|
| 291 |
|
---|
| 292 | <b>import org.apache.log4j.Logger;</b>
|
---|
| 293 | <b>import org.apache.log4j.BasicConfigurator;</b>
|
---|
| 294 |
|
---|
| 295 | public class HelloWorld {
|
---|
| 296 | <b>static Logger logger = Logger.getLogger(HelloWorld.class);</b>
|
---|
| 297 |
|
---|
| 298 | public static void main(String[] args) {
|
---|
| 299 | <b>BasicConfigurator.configure();</b>
|
---|
| 300 | <font color="blue"><b>logger.info("Hello World");</b></font> // the old SysO-statement
|
---|
| 301 | }
|
---|
| 302 | }
|
---|
| 303 | </pre>
|
---|
| 304 |
|
---|
| 305 | <p>Most of the modifications are "framework overhead" which has to be done once. The blue line is our "old System-out"
|
---|
| 306 | statement.</p>
|
---|
| 307 | <p>Don't try to run <tt>ant</tt> - you will only get lot of compiler errors. Log4J is not inside the classpath so we have
|
---|
| 308 | to do a little work here. But do not change the CLASSPATH environment variable! This is only for this project and maybe
|
---|
| 309 | you would break other environments (this is one of the most famous mistakes when working with Ant). We introduce Log4J
|
---|
| 310 | (or to be more precise: all libraries (jar-files) which are somewhere under <tt>.\lib</tt>) into our buildfile:</p>
|
---|
| 311 |
|
---|
| 312 | <pre class="code">
|
---|
| 313 | <project name="HelloWorld" basedir="." default="main">
|
---|
| 314 | ...
|
---|
| 315 | <b><property name="lib.dir" value="lib"/></b>
|
---|
| 316 |
|
---|
| 317 | <b><path id="classpath"></b>
|
---|
| 318 | <b><fileset dir="${lib.dir}" includes="**/*.jar"/></b>
|
---|
| 319 | <b></path></b>
|
---|
| 320 |
|
---|
| 321 | ...
|
---|
| 322 |
|
---|
| 323 | <target name="compile">
|
---|
| 324 | <mkdir dir="${classes.dir}"/>
|
---|
| 325 | <javac srcdir="${src.dir}" destdir="${classes.dir}" <b>classpathref="classpath"</b>/>
|
---|
| 326 | </target>
|
---|
| 327 |
|
---|
| 328 | <target name="run" depends="jar">
|
---|
| 329 | <java fork="true" <b>classname="${main-class}"</b>>
|
---|
| 330 | <b><classpath></b>
|
---|
| 331 | <b><path refid="classpath"/></b>
|
---|
| 332 | <font color="red"><b><path location="${jar.dir}/${ant.project.name}.jar"/></b></font>
|
---|
| 333 | <b></classpath></b>
|
---|
| 334 | </java>
|
---|
| 335 | </target>
|
---|
| 336 |
|
---|
| 337 | ...
|
---|
| 338 |
|
---|
| 339 | </project>
|
---|
| 340 | </pre>
|
---|
| 341 |
|
---|
| 342 | <p>In this example we start our application not via its Main-Class manifest-attribute, because we could not provide
|
---|
| 343 | a jarname <i>and</i> a classpath. So add our class in the red line to the already defined path and start as usual. Running
|
---|
| 344 | <tt>ant</tt> would give (after the usual compile stuff):</p>
|
---|
| 345 |
|
---|
| 346 | <pre class="output">
|
---|
| 347 | [java] 0 [main] INFO oata.HelloWorld - Hello World
|
---|
| 348 | </pre>
|
---|
| 349 |
|
---|
| 350 | <p>What's that? <ul>
|
---|
| 351 | <li><i>[java]</i> Ant task running at the moment</li>
|
---|
| 352 | <li><i>0</i> <font size="-1">sorry don't know - some Log4J stuff</font></li>
|
---|
| 353 | <li><i>[main]</i> the running thread from our application </li>
|
---|
| 354 | <li><i>INFO</i> log level of that statement</i>
|
---|
| 355 | <li><i>oata.HelloWorld</i> source of that statement</i>
|
---|
| 356 | <li><i>-</i> separator</li>
|
---|
| 357 | <li><i>Hello World</i> the message</li>
|
---|
| 358 | </ul>
|
---|
| 359 | For another layout ... have a look inside Log4J's documentation about using other PatternLayout's.</p>
|
---|
| 360 |
|
---|
| 361 |
|
---|
| 362 | <a name="config-files"></a>
|
---|
| 363 | <h2>Configuration files</h2>
|
---|
| 364 | <p>Why we have used Log4J? "It's highly configurable"? No - all is hard coded! But that is not the debt of Log4J - it's
|
---|
| 365 | ours. We had coded <tt>BasicConfigurator.configure();</tt> which implies a simple, but hard coded configuration. More
|
---|
| 366 | confortable would be using a property file. In the java source delete the BasicConfiguration-line from the main() method
|
---|
| 367 | (and the related import-statement). Log4J will search then for a configuration as described in it's manual. Then create
|
---|
| 368 | a new file <tt>src/log4j.properties</tt>. That's the default name for Log4J's configuration and using that name would make
|
---|
| 369 | life easier - not only the framework knows what is inside, you too!</p>
|
---|
| 370 |
|
---|
| 371 | <pre class="code">
|
---|
| 372 | log4j.rootLogger=DEBUG, <b>stdout</b>
|
---|
| 373 |
|
---|
| 374 | log4j.appender.<b>stdout</b>=org.apache.log4j.ConsoleAppender
|
---|
| 375 |
|
---|
| 376 | log4j.appender.<b>stdout</b>.layout=org.apache.log4j.PatternLayout
|
---|
| 377 | log4j.appender.<b>stdout</b>.layout.ConversionPattern=<font color="blue"><b>%m%n</b></font>
|
---|
| 378 | </pre>
|
---|
| 379 |
|
---|
| 380 | <p>This configuration creates an output channel ("Appender") to console named as <tt>stdout</tt> which prints the
|
---|
| 381 | message (%m) followed by a line feed (%n) - same as the earlier System.out.println() :-) Oooh kay - but we haven't
|
---|
| 382 | finished yet. We should deliver the configuration file, too. So we change the buildfile:</p>
|
---|
| 383 |
|
---|
| 384 | <pre class="code">
|
---|
| 385 | ...
|
---|
| 386 | <target name="compile">
|
---|
| 387 | <mkdir dir="${classes.dir}"/>
|
---|
| 388 | <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
|
---|
| 389 | <b><copy todir="${classes.dir}"></b>
|
---|
| 390 | <b><fileset dir="${src.dir}" excludes="**/*.java"/></b>
|
---|
| 391 | <b></copy></b>
|
---|
| 392 | </target>
|
---|
| 393 | ...
|
---|
| 394 | </pre>
|
---|
| 395 |
|
---|
| 396 | <p>This copies all resources (as long as they haven't the suffix ".java") to the build directory, so we could
|
---|
| 397 | start the application from that directory and these files will included into the jar.</p>
|
---|
| 398 |
|
---|
| 399 |
|
---|
| 400 | <a name="junit"></a>
|
---|
| 401 | <h2>Testing the class</h2>
|
---|
| 402 | <p>In this step we will introduce the usage of the JUnit [3] testframework in combination with Ant. Because Ant
|
---|
| 403 | has a built-in JUnit 3.8.2 you could start directly using it. Write a test class in <tt>src\HelloWorldTest.java</tt>: </p>
|
---|
| 404 |
|
---|
| 405 | <pre class="code">
|
---|
| 406 | public class HelloWorldTest extends junit.framework.TestCase {
|
---|
| 407 |
|
---|
| 408 | public void testNothing() {
|
---|
| 409 | }
|
---|
| 410 |
|
---|
| 411 | public void testWillAlwaysFail() {
|
---|
| 412 | fail("An error message");
|
---|
| 413 | }
|
---|
| 414 |
|
---|
| 415 | }</pre>
|
---|
| 416 |
|
---|
| 417 | <p>Because we dont have real business logic to test, this test class is very small: just show how to start. For
|
---|
| 418 | further information see the JUnit documentation [3] and the manual of <a href="OptionalTasks/junit.html">junit</a> task.
|
---|
| 419 | Now we add a junit instruction to our buildfile:</p>
|
---|
| 420 |
|
---|
| 421 | <pre class="code">
|
---|
| 422 | ...
|
---|
| 423 |
|
---|
| 424 | <target name="run" depends="jar">
|
---|
| 425 | <java fork="true" classname="${main-class}">
|
---|
| 426 | <classpath>
|
---|
| 427 | <path refid="classpath"/>
|
---|
| 428 | <path <b>id="application"</b> location="${jar.dir}/${ant.project.name}.jar"/>
|
---|
| 429 | </classpath>
|
---|
| 430 | </java>
|
---|
| 431 | </target>
|
---|
| 432 |
|
---|
| 433 | <b><target name="junit" depends="jar">
|
---|
| 434 | <junit printsummary="yes">
|
---|
| 435 | <classpath>
|
---|
| 436 | <path refid="classpath"/>
|
---|
| 437 | <path refid="application"/>
|
---|
| 438 | </classpath>
|
---|
| 439 |
|
---|
| 440 | <batchtest fork="yes">
|
---|
| 441 | <fileset dir="${src.dir}" includes="*Test.java"/>
|
---|
| 442 | </batchtest>
|
---|
| 443 | </junit>
|
---|
| 444 | </target></b>
|
---|
| 445 |
|
---|
| 446 | ...
|
---|
| 447 |
|
---|
| 448 | </pre>
|
---|
| 449 |
|
---|
| 450 | <p>We reuse the path to our own jar file as defined in run-target by giving it an ID.
|
---|
| 451 | The <tt>printsummary=yes</tt> lets us see more detailed information than just a "FAILED" or "PASSED" message.
|
---|
| 452 | How much tests failed? Some errors? Printsummary lets us know. The classpath is set up to find our classes.
|
---|
| 453 | To run tests the <tt>batchtest</tt> here is used, so you could easily add more test classes in the future just
|
---|
| 454 | by naming them <tt>*Test.java</tt>. This is a common naming scheme.</p>
|
---|
| 455 |
|
---|
| 456 | <p>After a <tt class="code">ant junit</tt> you'll get:</p>
|
---|
| 457 |
|
---|
| 458 | <pre class="output">
|
---|
| 459 | ...
|
---|
| 460 | junit:
|
---|
| 461 | [junit] Running HelloWorldTest
|
---|
| 462 | [junit] Tests run: 2, Failures: 1, Errors: 0, Time elapsed: 0,01 sec
|
---|
| 463 | [junit] Test HelloWorldTest FAILED
|
---|
| 464 |
|
---|
| 465 | BUILD SUCCESSFUL
|
---|
| 466 | ...
|
---|
| 467 | </pre>
|
---|
| 468 |
|
---|
| 469 | <p>We can also produce a report. Something that you (and other) could read after closing the shell ....
|
---|
| 470 | There are two steps: 1. let <junit> log the information and 2. convert these to something readable (browsable).<p>
|
---|
| 471 |
|
---|
| 472 | <pre class="code">
|
---|
| 473 | ...
|
---|
| 474 | <b><property name="report.dir" value="${build.dir}/junitreport"/></b>
|
---|
| 475 | ...
|
---|
| 476 | <target name="junit" depends="jar">
|
---|
| 477 | <b><mkdir dir="${report.dir}"/></b>
|
---|
| 478 | <junit printsummary="yes">
|
---|
| 479 | <classpath>
|
---|
| 480 | <path refid="classpath"/>
|
---|
| 481 | <path refid="application"/>
|
---|
| 482 | </classpath>
|
---|
| 483 |
|
---|
| 484 | <b><formatter type="xml"/></b>
|
---|
| 485 |
|
---|
| 486 | <batchtest fork="yes" <b>todir="${report.dir}"</b>>
|
---|
| 487 | <fileset dir="${src.dir}" includes="*Test.java"/>
|
---|
| 488 | </batchtest>
|
---|
| 489 | </junit>
|
---|
| 490 | </target>
|
---|
| 491 |
|
---|
| 492 | <b><target name="junitreport">
|
---|
| 493 | <junitreport todir="${report.dir}">
|
---|
| 494 | <fileset dir="${report.dir}" includes="TEST-*.xml"/>
|
---|
| 495 | <report todir="${report.dir}"/>
|
---|
| 496 | </junitreport>
|
---|
| 497 | </target></b>
|
---|
| 498 |
|
---|
| 499 | </pre>
|
---|
| 500 |
|
---|
| 501 | <p>Because we would produce a lot of files and these files would be written to the current directory by default,
|
---|
| 502 | we define a report directory, create it before running the <tt>junit</tt> and redirect the logging to it. The log format
|
---|
| 503 | is XML so <tt>junitreport</tt> could parse it. In a second target <tt>junitreport</tt> should create a browsable
|
---|
| 504 | HTML-report for all generated xml-log files in the report directory. Now you can open the ${report.dir}\index.html and
|
---|
| 505 | see the result (looks something like JavaDoc).<br>
|
---|
| 506 | Personally I use two different targets for junit and junitreport. Generating the HTML report needs some time and you dont
|
---|
| 507 | need the HTML report just for testing, e.g. if you are fixing an error or a integration server is doing a job.
|
---|
| 508 | </p>
|
---|
| 509 |
|
---|
| 510 |
|
---|
| 511 |
|
---|
| 512 |
|
---|
| 513 | <a name="resources"></a>
|
---|
| 514 | <h2>Resources</h2>
|
---|
| 515 | <pre>
|
---|
| 516 | [1] <a href="http://www.apache.org/dist/logging/log4j/1.2.13/logging-log4j-1.2.13.zip">http://www.apache.org/dist/logging/log4j/1.2.13/logging-log4j-1.2.13.zip</a>
|
---|
| 517 | [2] <a href="http://logging.apache.org/log4j/docs/manual.html">http://logging.apache.org/log4j/docs/manual.html</a>
|
---|
| 518 | [3] <a href="http://www.junit.org/index.htm">http://www.junit.org/index.htm</a>
|
---|
| 519 | </pre>
|
---|
| 520 |
|
---|
| 521 |
|
---|
| 522 |
|
---|
| 523 |
|
---|
| 524 | </body>
|
---|
| 525 | </html>
|
---|