Test the basics
There are multiple reasons for tests. Two major reasons are:
- To prove that a change of the software adds the desired functionality.
- To ensure that a change does not break the existing functionality (regression testing).
It is possible in these two cases that the tests are executed by hand, in an automatic way or with a mix of both. But automated tests provide a big benefit in terms of effort for regression tests.
In addition to these major reasons there is a third one, which is especially important for agile development. To fully understand this additional reason I have to digress first.
No perfect design
Software is malleable (meaning it is easy to change its form). This has advantages and disadvantages. One disadvantage is that each change can make the software worse (e.g. add a bug, remove some existing functionality unintentionally, …). The advantage is that the internal design can be changed. In particular, it means that the internal design can be improved. Why is this important? Because it is not possible to design the software in a perfect way at the start. Like the Spiral model the agile development model is an iterative model. This means that new requirements are added step by step and so almost ensuring that the initial design will not be the best design once the full list of requirements is known and implemented. Another reason for the inability to create a perfect design front-up is that during the implementation developers get new insights into the domain and this usually also means a design change. So it is an ongoing task to improve the design of the software to make it reflect the domain in a good way, to be easy to understand and to extend. You ask but how is this related to tests?
One can view a program under development as the space, which the developer(s) can form between two fixed ends. On the bottom end are the things the developer and so the new program depend on. These might be the JDK, 3rd-party libraries, a data base, the operation system or the file system. This bottom is fixed because the developer can not change these interfaces (easily). On the top end are the requirements. They are fixed, too, and are in the best case encoded in some automatic acceptance tests. One can describe the primary task of the developer to fill this space with some code to use the existing components (e.g. JDK) to provide the requested functionality. In this primary task the developer has full freedom. She can create a huge god class. Or, even more drastic, she can write an i386 simulator in Java and write the business code in assembler. As long as the requirements are met the customer (usually) doesn’t care.
Bringing all together
But there is another aspect in the job of the developer (which distinguish a coder from a software engineer): to provide a software with a good internal quality (design, code layout, names, OO design, loose coupling,…) to make the software easy to understand and maintain. To achieve and keep such a good internal quality the internal quality of the software needs to be constantly monitored and improved with smaller or larger re-designs.
Because such re-designs are required by new requirements and insights, AND such re-designs require code changes, AND because software is malleable, such changes can break existing functionality. So without tests it is time-consuming to improve the internal quality because extensive manual re-tests are required. If there are no or only limited automatic tests, usually the re-design is not executed and the internal quality of the software will degenerate over time with the known effects of increased cost for maintenance and reduced adaptability regarding new features.
To sum up, automatic tests (whether they are written before or after the implementation) are indispensably for achieving and maintaining a high internal software quality when an agile development model is used.