Generally, the acceptance testing and unit testing performed by an agile team facilitates collaboration and communication, creates feedback loops, and gives developers the courage to attempt things they would perhaps normally shy away from. A test-driven approach to development causes high-quality solutions and implementations to emerge.
Acceptance tests are written by the on-site customer. This allows the on-site customer to inject their domain knowledge directly into the development effort. Acceptance tests are the result of the conversations prompted by the user stories, which occur between the onsite customer and the developers at the start of each iteration. They capture the details of the user stories and assert their behavior, as well as defining the acceptance criteria. The acceptance tests also create a feedback loop between the on-site customer and the developers. The acceptance tests should be executed regularly by the automated build process. This provides greater visibility of progress to the onsite customer in terms of passing and failing acceptance tests. At the start of an iteration the acceptance tests will fail, but as more user stories are completed more acceptance tests will pass. Once an acceptance test passes, should it begin to fail (perhaps due to a recent change), the problem should be fixed immediately so that the test is made to pass once again. This continuous and visible feedback enables the on-site customer to steer the iteration and development effort more effectively.
Using a framework such as Fit allows the on-site customer to construct acceptance tests in a tabular format, e.g. a spreadsheet or HTML table. The developers then write fixtures linking the tables to the software under test so that the acceptance tests can be executed automatically.
Writing automated unit tests as part of test-driven development guide the evolutionary design of software and, by asserting class behavior at a method level, provide effective documentation.
Developing software using automated unit tests is empowering because inside the test-driven cycle: test->code->refactor they serve as constant indicators and reminders and allow developers to code, integrate and build in baby steps. Run frequently by the automated build process, automated unit tests provide a meaningful measure of progress. The unit tests should always complete with a green light. Those that fail with a red light should be fixed immediately so that working, executable software is always available. Automated unit tests, providing a very high code coverage (>85%), act as a safety net for developers. This safety net gives developers the courage to make changes because broken code is quickly highlighted and the cause is easily traced because the tests are run so often.