Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

Introduction

Test-driven development (TDD) is a software development technique that is based on the repetition of a short development cycle. The developer writes an automated test that is designed to fail at first, but will pass once that designed improvement or enhancement is complete. The developer then first writes code to pass the test, and then improves the code to continue to pass the test, but in the most logical and best written way. TDD can be used with writing new projects, or even to improve existing legacy code. One fundamental philosophy of TDD is that instead of coding for today and designing for tomorrow, one codes for tomorrow and designs for today.

TDD Cycle

(from Test-Driven Development by Example)

  1. Add a test
    Each new feature begins with writing a test. The test is designed to fail, as the feature has not been implemented yet. If the test passes, the feature is not needed. In order to write the test, the developer must understand the feature's specification, requirements, and exception conditions. This is the primary difference from writing tests after the code is written, as the testing drives the development and ensures the developer focuses on the requirements before writing their code.
  2. Run all existing tests and see if the new one fails
    This verifies that everything else is working correctly, and that the desired functionality is not present as of yet within the code. This helps ensure the newly written test will only pass when the desired functionality is added.
  3. Write some code
    Next, the developer writes code to merely make the test pass. The code is only designed to do this, nothing further, and not necessarily in the best possible way.
  4. Run the automated tests and see them succeed
    If the new test now passes, the developer has written the functionality desired.
  5. Refactor code
    Finally, the code needs to be cleaned up. The test should be ran repeatedly, making sure that the refactoring does not break the newly introduced code.

This cycle is repeated with each desired piece of functionality. If at any point other tests besides the newly introduced test fail, the developer should revert instead of undergoing extensive debugging. The goal is small runs repeated often, giving easily revertible checkpoints.

Benefits

Studies have found that TDD improves developer productivity. By testing every piece of code, developers can gain a greater level of trust of their code. TDD also helps developers tackle small pieces of a project when necessary. Despite the additional amount of test code, total code implementation time is usually shorter, and large endemic problems are discovered before they are given the chance to grow. It also leads to more modular and flexible code, as small projects are undertaken often, forcing the developer to code in such manageable segments.

Limitations

Some products are hard to test, such as user interfaces or those that need a specific network configuration. Management must support TDD, as otherwise the time spent writing tests can easily be attributed as wasted time. Tests must be written properly, as badly written tests can require significant effort to maintain or even lead to false positives leading to the ignoring of tests. Tests must be all run throughout the process, if a large number of tests fail late in the development cycle they must be individually fixed instead of rashly adjusted. If a developer fails to have an accurate understanding of the requirements for a module, their test will be incorrect, as will the code written for that test. Finally, TDD might lure developers into a false sense of security, leading them to skip testing such as integration testing or compliance testing.