Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: first the developer writes a failing automated test case that defines a desired improvement or new function, then produces code to pass that test and finally refactors the new code to acceptable standards. Kent Beck, who is credited with having developed or 'rediscovered' the technique, stated in 2003 that TDD encourages simple designs and inspires confidence.
Test-driven development is related to the test-first programming concepts of extreme programming, begun in 1999, but more recently has created more general interest in its own right.
Programmers also apply the concept to improving and debugging legacy code developed with older techniques.1
- Write new code only if an automated test has failed
- Eliminate duplication
- We must design organically, with running code providing feedback between decisions
- We must write out own tests, because we can;t wait 20 times per day for someone else to write a test
- Out development environment must provide rapid response to small changes
- Out design must consist of many highly cohesive, loosely coupled component, just to make testing easy
- Red — Write a little test that doesn't work, and perhaps doesn't event complie at first
- Green — Make the test work quickly, committing whatever sins neccessary in the process
- Refactor — Eliminate all of the duplication creating in merely getting the test to work
- Write a test. Think about how you would like the operation in your mind to appear in your code. You are writting a story. Invent the interface you wish you had. Include all of the elements in the story that you imagine will be neccessary to calculate the right answer.
- Make it run. Quickly getting that bar to go to green dominates everything else. If a clean, simple solution is obvious, then type it in. If the clean, simple solution is obvious but it will take you a minute, then make a note of it and get back to the main problem, which is getting the bar grden in seconds. This shift in assthetics is hard for some experienced software engineers. They only know how to follow the rules of good engineering. Quick green excuses all sins. But only for a moment.
- Make it right. Now that the system is behaving, put the sinful ways of the recent past behind you. Step back onto the straight and narrow path of software righteousness. Remove the duplication that you introduced, and get to green quickly.
Test-driven development (TDD) (Beck 2003; Astels 2003), is an evolutionary approach to development which combines test-first development where you write a test before you write just enough production code to fulfill that test and refactoring. What is the primary goal of TDD? One view is the goal of TDD is specification and not validation (Martin, Newkirk, and Kess 2003). In other words, it’s one way to think through your requirements or design before your write your functional code (implying that TDD is both an important agile requirements and agile design technique). Another view is that TDD is a programming technique. As Ron Jeffries likes to say, the goal of TDD is to write clean code that works. I think that there is merit in both arguments, although I lean towards the specification view, but I leave it for you to decide.2
Kent Beck, who popularized TDD in eXtreme Programming (XP) (Beck 2000), defines two simple rules for TDD (Beck 2003). First, you should write new business code only when an automated test has failed. Second, you should eliminate any duplication that you find. Beck explains how these two simple rules generate complex individual and group behavior:3
- You develop organically, with the running code providing feedback between decisions.
- You write your own tests because you can't wait 20 times per day for someone else to write them for you.
- Your development environment must provide rapid response to small changes (e.g you need a fast compiler and regression test suite).
- Your designs must consist of highly cohesive, loosely coupled components (e.g. your design is highly normalized) to make testing easier (this also makes evolution and maintenance of your system easier too).
For developers, the implication is that they need to learn how to write effective unit tests. Beck’s experience is that good unit tests:4
- Run fast (they have short setups, run times, and break downs).
- Run in isolation (you should be able to reorder them).
- Use data that makes them easy to read and to understand.
- Use real data (e.g. copies of production data) when they need to.
- Represent one step towards your overall goal.
- Introduction to Test Driven Development (TDD) - Test-driven development (TDD) (Beck 2003; Astels 2003), is an evolutionary approach to development which combines test-first development where you write a test before you write just enough production code to fulfill that test and refactoring.
- The Art of Agile Development: Test-Driven Development - We produce well-designed, well-tested, and well-factored code in small, verifiable steps.
- An Introduction to the Art of Unit Testing in PHP - Testing is an essential aspect of developing in any programming language. If you don't test your source code then how can you verify it works as expected? Manual testing can only be performed irregularly and usually only in limited ways. The answer to testing source code regularly, and in depth, is to write automated tests which can be frequently executed. In PHP such tests are usually written using a unit testing framework, a framework which allows the source code of any application or library to be tested as isolated units of functionality such as a single class or method.
- PHPUnit Automated Unit Testing Framework
- Tutorial: Introduction to Unit Testing in PHP with PHPUnit
- Let's TDD a Simple App in PHP
- Agile DevOps: Test-driven infrastructure
- Design Driven Testing