18

Click here to load reader

INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

Embed Size (px)

Citation preview

Page 1: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

INTRODUCTION TO JAVA PROGRAMMING

JAVA FUNDAMENTALS PART 2

Page 2: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

Table of Contents Introduction to JUnit 4

What is a Test Driven approach? 5

The benefits of a Test Driven Approach 6

What is Continuous Integration? 6

What benefits does using JUnit with Continuous Integration give us? 7

JUnit Documentation 9

First Junit Test 9

Introduction to ANT 21

Ant and Continuous Integration 22

Getting Started with ANT 24

Simple ANT files 25

Multiple ANT files 35

Overview of java.util package 46

Lists 46

Arrays 48

ArrayList 48

Vectors 48

Using Collections class to synchronize lists 49

LinkedList and Deque interface 54

Maps 57

Comparable interface: 66

Deque 67

Set 71

Overview of java.io package 75

java.io.File 76

java.io.File.ShowUseOfFile 84

Listing Files 86

Buffered Reader and Writer 89

Inputstreams 100

Overview of threads 111

Using Runnable 111

Page 3: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

Overview of javax.swing package 166

Page 4: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach * Benefits of a Test Driven Approach * Overview of Continuous Integration * Benefits of using JUnit with Continuous Integration This section has examples of code that can be found in the /junit/01_example of this section. If you would like to compile or run the code please download this examples. JUnit is a java library used for unit testing. Unit testing is used for testing small units of code. Tests need to be written to test all units of code. If all units of code are tested we have 100% code coverage. Junit is a tool used by Agile Programming. Agile Programming Methodology uses a Test Driven approach to writing code. This means that one writes tests before one writes the code. JUnit is a useful library for writing unit tests.

JUnit has a test runner class that can be run from your main method. Alternatively you can set up ANT to run your JUnit tests using an Ant based runner. ANT is a build tool which uses XML configuration files. You can configure ANT to compile, package, run your junit tests and deploy your code. JUnit can be configured to produce XML reports on the tests that it runs. These XML reports can be converted to Web Pages. Agile Programming Methodology is an avid user of Continuous Integration. If JUnit is used in conjunction with tools such as Ant, Cruise Control and Subversion it becomes a useful tool for Continuous Integration.

Page 5: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

What is a Test Driven approach?

A Test Driven approach is one where you write your tests before you write your code. When using Junit this means that you write you Test Case class before you write any of your interfaces or implementation classes. This may seem a bit bizarre at the beginning for your Test Case will not even compile as none of the interfaces or implementation classes you are testing even exist. So the steps of a Test Driven approach are as follows: * Write your Test Case. Refer to classes and interfaces that do not already exist in your project. Code all your expected Responses. The expected responses are what you expect the implementation methods you have not written yet will return.

* Write skeleton code for your interfaces and implementation classes so that your Test Case is able to compile. For example if an implementation class has a method that returns a value get it to return an empty string or null temporarily.

* Now run your Test Case. Your Test Case will fail at this moment in time as your implementation methods are returning empty strings or nulls instead of the expected response.

* Keep implementing your classes and re-running the unit tests until the Test Case you originally coded passes.

* While implementing a class we may write pseudo code that calls another method that does not yet exist. Now is the time then to create another unit test for this method! After writing the unit test for this method, implement the method.

* REMEMBER: WRITE your test BEFORE writing the implementation classes.

The temptation is to write your implementation classes before you write your tests, but read on to see why writing your test before you write the implementation code is so IMPORTANT!

Page 6: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

The benefits of a Test Driven Approach

There are many benefits of a Test Driven Approach: It encourages 100% code coverage by JUnit tests. Remember that re-factoring the code base to make it more elegant, reusable, understandable and efficient becomes a low risk activity if there is 100% code coverage: Any accidental mistakes in the re-factoring will immediately be flagged by Continuous Integration tools such as Cruise Control. Writing your test first encourages one to make the code so it can be tested in the first place. Often code that has not had the unit test written first needs to be re-factored before it can be tested which is in itself a risky activity.

Writing your test first prevents you wasting your time building some sophisticated framework that does everything only to discover at a later moment in time that is problematic. For example the framework may have lots of bugs and the original requirements that inspired its creation may have since changed making the framework more of a hindrance than a help. Unit tests inspire you to get the minimum work done to pass the test. As the requirements become more particular so can the unit tests be modified to reflect the new requirements. Unit tests are consequently very much the corner stone of Agile Programming they create an agile approach to programming that is results based. Having 100% code coverage of the code by JUnit tests allows the code to be continuously re-factored or modified.

What is Continuous Integration? Cruise Control notices that a developer has checked some code into the Subversion Code Repository. A Code repository is a database where programmers share code. Subversion is a popular Code Repository program. It was written by some of the Guys who wrote CVS, but is better. Cruise Control waits for example 5 minutes after the last bit of code was checked in and then triggers all the code to be checked out to a certain directory on the machine hosting Cruise Control. The time it waits after the last bit of code was checked in is a configurable attribute. After all the code is checked out Ant tasks are triggered to compile and package the code. Another Ant task triggers the JUnit tests to run. JUnit tests are written in Java to test small units of Java Code. The results of the build and JUnit tests can be published in HTML format. If the build process or unit testing fails, emails are automatically sent to Developers.

What benefits does using JUnit with Continuous Integration give us? By using JUnit in conjunction with ANT, Cruise Control and Subversion, one can be

Page 7: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

reasonably sure that any modifications, deletions or re-factorings of the code base that have been done in error will cause the Ant build or JUnit tests to fail. Re-factoring means changing the code so that it becomes more reusable, maintainable, understandable and if necessary more efficient. Failures will be brought to everyone’s attention. This means that the problems can be immediately solved. Without Continuous Integration problems may not be noticed before the code gets handled over to the formal testing team. By catching error early on one is in a better position to produce bug free code. Catching errors in real time without having to go through many formal testing cycles saves money. Continuous Integration reduces reliance on formal testing. This is good because formal testing is expensive. Formal testing involves taking snapshots of code, passing builds across to the testing team. These snapshots of code may become separate branches in the code repository (Subversion).

Branching means is that the developers continue working and introducing new features on the main code base while the testers test the code on the other code branch. Bug reports are sent to the developers who will often fix the bug on both branches. After the fixes a new snapshot of the code is taken, a build produced and passed over to the testers to test whether the bugs have indeed been fixed. Shoving the code backwards and forwards between the formal testers and the developers is both a costly and time consuming process. Thus producing bug free code in the first place using Continuous Integration is both a time and cost saver. Without unit testing and Continuous Integration, re-factoring becomes risky and expensive. Developers are too timid to change existing code out of fear that it will create lots of new bugs which will only become evident when the code is passed over to the formal testing team. These same developers will consequently not change the code to make it more reusable, maintainable, understandable or efficient. The code base will gradually deterioate to the extent that at some point in time, upper management will take the radical decision to totally replace the system at a serious expense!

However in cases where Continuous Integration is used, re-factoring becomes a low risk activity as any mistakes in the re-factoring are instantaneously brought to everyone’s attention. Developers are consequently more likely too re-factor code.\

Page 8: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

JUnit Documentation This section has examples of code that can be found in the /junit/01_example folder of the examples. If you would like to compile or run the code please download Examples. You can download JUnit from: www.junit.org Download the latest non beta version. At the time of writing this was:e.g. junit4.8.zip The following files in the zip file are pretty useful: /README.html This README points you to other resources /doc/faq/faq.htm This FAQ is pretty good This has good javadocs.

First Junit Test This section introduces you to writing JUnit tests using annotations Start by looking at the class we wish to test. You can find the source in the following location: /08_junit/03_example/SVN_LOCAL/implementation/src/com/jjpeople/hellouniverse/HelloUniverse.java Source Code: A01 /* A02 * @author JDickerson A03 * Created on 15 Oct 2008 A04 */ A05 package com.jjpeople.hellouniverse; A06 A07 import java.text.DateFormat; A08 import java.text.SimpleDateFormat; A09 import java.util.Date; A10 A11 import org.apache.log4j.BasicConfigurator; A12 import org.apache.log4j.Logger; A13 A14 /** A15 * Class implementing behaviour to say hello to the universe A16 * A17 * @author JDickerson A18 * Created on 15 Oct 2008 A19 */ A20 public class HelloUniverse {

Page 9: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

A21 A22 public static final String AGE_OF_UNIVERSE = A23 "3.7 +/- 0.2 Gyr where one Gyr is 10 ^ 24"; A24 A25 // Telling logger to log this class A26 public static final Logger logger = A27 Logger.getLogger( HelloUniverse.class ); A30 /** A31 * Constructor A32 */ A33 public HelloUniverse() { A34 A35 super(); A36 } A39 /** A40 * Method saying hello to the universe, the age of the universe and A41 * the current time A42 * A43 * @param time current time A44 * @return the message to say hello to the universe with A45 */ A46 public String sayHello( String time ) { A47 A48 String message = A49 "Hello Universe! Your age is " + AGE_OF_UNIVERSE A50 + " and the time is: " + time; A51 A52 return message; A53 } A56 /** A57 * Entry point to application A58 * A59 * @param args arguments to pass to this application from the command line. A60 * There are no command line arguments for this application. A61 */ A62 public static void main(String[] args) { A63 A64 BasicConfigurator.configure(); A65 A66 HelloUniverse helloUniverse = new HelloUniverse(); A68 DateFormat timeFormat = new SimpleDateFormat( "hh:mm:ss" );

Page 10: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

A69 A70 String time = timeFormat.format( new Date() ); A71 A72 String message = helloUniverse.sayHello( time ); A73 logger.info( message ); A74 } A75 } The methods we wish to test are sayHello(..) Now lets look at at the unit test. You can find the source in the following location: /08_junit/03_example/SVN_LOCAL/junit/src/com/jjpeople/hellouniverse/HelloUniverseTest.java Source Code: B002 * @author JDickerson B003 * Created on 15 Oct 2008 B004 */ B005 package com.jjpeople.hellouniverse; B006 B007 // You can import static methods B008 import static org.junit.Assert.assertEquals; B010 import java.text.DateFormat; B011 import java.text.SimpleDateFormat; B012 import java.util.Date; B014 import org.apache.log4j.BasicConfigurator; B015 import org.apache.log4j.Logger; B016 import org.junit.After; B017 import org.junit.AfterClass; B018 import org.junit.Before; B019 import org.junit.BeforeClass; B020 import org.junit.Test; B023 /** B024 * Test class testing functionality of B025 * com.jjpeople.hellouniverse.HelloUniverseTest B026 * B027 * @author JDickerson B028 * Created on 15 Oct 2008 B029 */ B030 public class HelloUniverseTest { B031 B032 public static final Logger logger = B033 Logger.getLogger( HelloUniverseTest.class );

Page 11: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

B034 B035 private static HelloUniverse helloUniverse; B036 B037 private Date date; B038 B039 @BeforeClass B040 public static void oneTimeSetUp() { B041 B042 // one-time initialization code gets called before all tests B043 logger.debug( B044 "In method oneTimeSetUp() which has annotation @BeforeClass" ); B045 B046 helloUniverse = new HelloUniverse(); B047 } B050 @AfterClass B051 public static void oneTimeTearDown() { B052 B053 // one-time initialization code gets called before all tests B054 logger.debug( B055 "In method oneTimeSetUp() which has annotation @AfterClass" ); B056 B057 helloUniverse = new HelloUniverse(); B058 } B059 B060 B061 @Before B062 public void setUp() { B063 B064 // Gets called before each test method that is annotated with B065 // the word @Test B066 B067 logger.debug( B068 "In method setUp() which has annotation @Before" ); B069 B070 date = new Date(); B071 } B072 B073 B074 @After B075 public void teadDown() {

Page 12: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

B076

B077 // Gets called after each test method that is annotated with B078 // the word @Test B079 B080 logger.debug( B081 "In method teadDown() which has annotation @After" ); B082 } B083 B084 B085 @Test B086 public void testSayHello() { B087 B088 // This method test the sayHello() method of HelloUniverse B089 B090 DateFormat timeFormat = new SimpleDateFormat( "hh:mm:ss" ); B091 B092 String time = timeFormat.format( date ); B093 B094 String expected = B095 "Hello Universe! Your age is " + HelloUniverse.AGE_OF_UNIVERSE + B096 " and the time is: " + time; B097 B098 logger.debug( "expected = \n[" + expected + "]" ); B099 B100 String actual = helloUniverse.sayHello( time ); B101 B102 logger.debug( "actual = \n[" + actual + "]" ); B103 B104 assertEquals( expected, actual ); B105 } B108 // You make your JUnit 4 test classes accessible to a TestRunner designed B109 // to work with earlier versions of JUnit, declare a static method suite B110 // that returns a test. B111 // public static junit.framework.Test suite() { B112 // B113 // return new JUnit4TestAdapter( HelloUniverseTest.class ); B114 // } B115 B116 B117 /**

Page 13: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

B118 * Entry point to this Test B119 * B120 * @param args arguments to be passed to this application. This application B121 * expects no arguments B122 */ B123 public static void main( String args[] ) { B124 B125 BasicConfigurator.configure(); B126 B127 //This runs the classes without running the asserts: B128 // org.junit.runner.JUnitCore.runClasses( HelloUniverseTest.class ); B129 B130 // This runs the tests B131 org.junit.runner.JUnitCore.main( HelloUniverseTest.class.getName() ); B132 } B133 } Lets start by looking at the main() method of the test class. A runner is used to run the test: B123 public static void main( String args[] ) { B124 B125 BasicConfigurator.configure(); B126 B127 //This runs the classes without running the asserts: B128 // org.junit.runner.JUnitCore.runClasses( HelloUniverseTest.class ); B129 B130 // This runs the tests B131 org.junit.runner.JUnitCore.main( HelloUniverseTest.class.getName() ); B132 } The main() method of the test runner, JUnitCore loads up the class and inspects it for annotations. Annotations are those names on the top of methods that start with an @ sign. For example: B039 @BeforeClass B050 @AfterClass B061 @Before B074 @After

Page 14: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

B085 @Test The @Test annotation appears above the test methods. Before executing each and every test method the runner will invoke the method that is annotated with @Before. The idea is that you add code to the @Before method to set up the environment for that test. After executing a given test method the runner will invoke the method that is annotated by @After. The idea is that you add code to the @After method that tidies up the environment after the test. Methods annotated by @Before Class are invoked only once and just before invoking any of the @Before or @Test methods. These methods are used to set up the environment for all of the tests. Methods annotated by @After Class are invoked only once and just after invoking all the @Test and @After methods. These methods are used to tidy up the environment for all the tests. Explanation of @Test The @Test annotation is telling the runner that the method is a test method: B085 @Test B086 public void testSayHello() { B087 B088 // This method test the sayHello() method of HelloUniverse B089 B090 DateFormat timeFormat = new SimpleDateFormat( "hh:mm:ss" ); B091 B092 String time = timeFormat.format( date ); B093 B094 String expected = B095 "Hello Universe! Your age is " + HelloUniverse.AGE_OF_UNIVERSE + B096 " and the time is: " + time; B097 B098 logger.debug( "expected = \n[" + expected + "]" ); B099 B100 String actual = helloUniverse.sayHello( time ); B101 B102 logger.debug( "actual = \n[" + actual + "]" ); B103 B104 assertEquals( expected, actual ); B105 }

Page 15: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

This test method is invoked by the runner after it has invoked: (a) The method annotated by @BeforeClass (b) The method annotated by @Before The key line in this test method is the assertEquals(..) line: B104 assertEquals( expected, actual ); The assertEquals method is a static test method that was imported on line B008: B008 import static org.junit.Assert.assertEquals; The assertEquals method compares expected results against actual results If the expected results are different from actual respects the test fails. In the case of this example, however expected is equal to actual so the test passes and the following output is written to the console: C01 JUnit version 4.5 C02 0 [main] DEBUG com.jjpeople.hellouniverse.HelloUniverseTest _ - In method oneTimeSetUp() which has an C03 notation @BeforeClass C03 .16 [main] DEBUG com.jjpeople.hellouniverse.HelloUniverseTest _ - In method setUp() which has annotation @Before C04 31 [main] DEBUG com.jjpeople.hellouniverse.HelloUniverseTest _ - expected = C05 [Hello Universe! Your age is 3.7 +/- 0.2 Gyr where one Gyr is _ 10 ^ 24 and the time is: 03:28:27] C06 31 [main] DEBUG com.jjpeople.hellouniverse.HelloUniverseTest _ - actual = C07 [Hello Universe! Your age is 3.7 +/- 0.2 Gyr where one Gyr is _ 10 ^ 24 and the time is: 03:28:27] C08 62 [main] DEBUG com.jjpeople.hellouniverse.HelloUniverseTest - _ In method teadDown() which has annotation @After C10 62 [main] DEBUG com.jjpeople.hellouniverse.HelloUniverseTest - _ In method oneTimeSetUp() which has a annotation @AfterClass C11 C12 Time: 0.078 C13 C14 OK (1 test) Note that there are many different assert methods depending on the type of objects you are comparing the expected results against the actual results with. To see the javadocs for these assert methods: You can download JUnit from:

Page 16: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

www.junit.org e.g. junit4.8.zip Unzip it and take a look at:

/javadoc/index.html Take a look at the following class: org.junit.Assert for the different assert methods available. The methods which are not

deprecated include: static void assertArrayEquals(byte[] expecteds, byte[] actuals) Asserts that two byte arrays are equal. static void assertArrayEquals(char[] expecteds, char[] actuals) Asserts that two char arrays are equal. static void assertArrayEquals(int[] expecteds, int[] actuals) Asserts that two int arrays are equal. static void assertArrayEquals(long[] expecteds, long[] actuals) Asserts that two long arrays are equal. static void assertArrayEquals( java.lang.Object[] expecteds, java.lang.Object[] actuals) Asserts that two object arrays are equal. static void assertArrayEquals(short[] expecteds, short[] actuals) Asserts that two short arrays are equal. static void assertArrayEquals( java.lang.String message, byte[] expecteds, byte[] actuals) Asserts that two byte arrays are equal. static void assertArrayEquals( java.lang.String message, char[] expecteds, char[] actuals) Asserts that two char arrays are equal. static void assertArrayEquals( java.lang.String message, int[] expecteds, int[] actuals) Asserts that two int arrays are equal. static void assertArrayEquals( java.lang.String message, long[] expecteds, long[] actuals) Asserts that two long arrays are equal.

Page 17: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

static void assertArrayEquals( java.lang.String message, java.lang.Object[] expecteds, java.lang.Object[] actuals) Asserts that two object arrays are equal. static void assertArrayEquals( java.lang.String message, short[] expecteds, short[] actuals) Asserts that two short arrays are equal. static void assertEquals(double expected, double actual, double delta) Asserts that two doubles or floats are equal to within a positive delta. static void assertEquals(long expected, long actual) Asserts that two longs are equal. static void assertEquals(java.lang.Object expected, java.lang.Object actual) Asserts that two objects are equal. static void assertEquals( java.lang.String message, double expected, double actual, double delta) Asserts that two doubles or floats are equal to within a positive delta. static void assertEquals( java.lang.String message, long expected, long actual) Asserts that two longs are equal. static void assertEquals( java.lang.String message, java.lang.Object expected, java.lang.Object actual) Asserts that two objects are equal. static void assertFalse(boolean condition) Asserts that a condition is false. static void assertFalse(java.lang.String message, boolean condition) Conclusion It is better to write your unit tests before you even write the code. This is called Test Driven Development. An Agile Developer may develop his code as follows:

Page 18: INTRODUCTION TO JAVA PROGRAMMING JAVA FUNDAMENTALS PART 2 · Introduction to JUnit This section gives you an introduction to junit: * Overview of jUnit * Overview of Test Driven Approach

Create a Unit Test, including the assert methods. The code makes references to interfaces it is testing that do not even exist yet so the code

does not compile Implement the interfaces of the code we are testing and if necessary some of the classes. If it is necessary to implement the classes so that the code compiles then do so but do not at this stage implement the bodies of the methods. If a method returns something just temporarily return null. Try and compile the Unit Test. It should now compile but will not pass the test. Now start implementing the classes that implement the interfaces.

Use a "Top to Bottom" approach. What this means is that we start at the top (i.e. the methods we are testing in the unit test) and then decide as we go along what other public, friendly, protected or private methods we require. As you develop these other methods, you may put your current development for the test in question on hold and develop the unit test for one of these nearer the "bottom" methods. Once the unit test of one of these "Nearer the Bottom" methods passes then resume development of the original test method you commenced development with. Using this Agile "Top to Bottom" approach to development of code provides discipline to the coding experience. This approach encourages creating code when is only strictly necessary. It tends to speed up development and produce bug free and streamlined code. Try this "top to bottom" approach using unit testing and you will be surprised at how you will be able to implement complex code quickly. You will find that adopting a "top to bottom" approach will make you ask the right questions to yourself. You will be forced to ask the correct questions and subsequently answer them correctly by the "Top to bottom" unit test methodology itself.

Introduction to ANT Ant is an open source build tool written in Java which uses XML to configure builds related tasks useful for Agile Programming. Among other tasks, it can be used for compiling, packaging, testing and deploying applications. There are lots of core tasks bundled with Ant and also lots of other third party tasks. If you cannot find a task to do the job you can always create an Ant task yourself.

Ant and Agile Programming Methodology Agile Programming Methodology is about bringing the business, development and testing closer together. Continuous Integration provides real time testing of the code base and brings testing and development closer together. By using Ant in conjunction with Cruise Control and Subversion, one can be reasonably sure that any modifications, deletions or re-factorings of the code base that have been done in