Testing is about predicting the future!

Testing is about predicting the future!

Test-first development is an old concept that was rediscovered and documented by Kent Beck in Extreme Programming Explained (Chapter 13 in the Second Edition).  Test-first development (TFD) is an approach to development in which developers do not write a single line of code until they have created the test cases needed to prove that unit of work solves the business problem and is technically correct at a unit-test level. In a response to a question on Quora, Beck described reading about developers using a test-first approach well before XP and Agile. Test-driven development is test-first development combined with design and code refactoring.  Both test-first and test-driven development  are useful for improving quality, morale and trust and even though both are related they not the same.

A little more history.  Test-first programming / development was introduced (or re-introduced) as a primary practice of Extreme Programing in Chapter 7 of Extreme Programing Explained (page 50). Test-driven development as a method was described in Test Driven Development: By Example (2003, perhaps we will re-read this book in the future), and is an evolution of the test-first concept.

Test-first development has a few basic steps.

  1. The developer accepts a unit of work and writes a set of tests that will prove that the code actually functions correctly at a unit level.
  2. They then run the tests.  The tests should fail because the code to solve the business problem embedded in the unit of work has not been written.  If the tests pass, rewrite them so that they fail (assuming someone else has not fixed the problem).
  3. Write the code needed to solve the problem. Remember that simplicity is king and only write enough code to solve the problem.
  4. Run the test suite again. If the tests pass you are done; however, if ANY of the tests doesn’t pass return to step three and correct the code.  Repeat steps three and four until all tests pass.

Test-driven development, TDD (also known as test-driven design) adds one additional “step” to the process after the unit tests.

  1. Refactor the code and design to make both as simple as possible and remove any possible duplication.

As the code is written and refactored the design evolves based on the feedback gathered one story at a time. TDD integrates the practice of coding and unit testing with evolutionary design, breaking down the separation of roles that reduce collaboration and increase the cost of quality. A conceptual advance; however, there are organizations such as ATMs, automotive products and medical devices where the concept of evolutionary design is a bridge too far, leaving test first as their only option.

In TDD by Example, Beck identifies two “rules” for TDD that not directly identified in the introduction of TFD.  The first is to never write a line of code until you have written a failing automated test and the second is to avoid duplication. TFD recognized the need to combine manual and automated unit tests.  Both of these rules could be applied (and should be if possible) for both TDD and TFD, and in the long run are just good practice.

The only significant difference between test-first and test-driven development is a biggie – the inclusion of using the coding and unit testing feedback loop as a tool to propel incremental and emergent design techniques.