A closer look at TDD
The evolution of TDD
TDD is one of the technical practices of eXtreme Programming. The invention of TDD is usually attributed to Kent Beck; one of the first “extreme programmers”.
This practice shook the common sentiment of programmers at the time.
The practice of testing was already widespread, but no one before had ever suggested writing tests before writing the actual code that needs testing.
This act is itself counterintuitive if one thinks of TDD as a testing practice.
TDD as a design practice
TDD thus began as a practice related to testing, but it soon turned out that the resulting tests were just a nice side-effect.
The point of writing tests before code had much more to do with the design of the code itself than its testing.
Writing the test before the code helps the programmer put himself in the shoes of the user, making it easier to create clear software APIs.
Using TDD helps make you more comfortable with circumscribing the scope of your code, writing shorter but more focused code, and producing easily composable modules.
Test-driven development cycle
A graphical representation of the test-driven development lifecycle The following sequence is based on the book Test-Driven Development by Example:[2]
Add a test
Run all tests. The new test should fail for expected reasons
Write the simplest code that passes the new test
All tests should now pass
Refactor as needed, using tests after each refactor to ensure that functionality is preserved
What is done in refactoring?
Some examples of refactoring:
moving code to where it most logically belongs
removing duplicate code
making names self-documenting
splitting methods into smaller pieces
re-arranging inheritance hierarchies
The simplest thing that works
The act of thinking about how to test code early in the process helps with imagining concrete examples.
In addition, this allows the developer to focus on concrete cases, avoiding premature generalizations and optimizations.
“The simplest thing that could possibly work” is a phrase you often hear from long-time XP programmers.
Extensive testing is no longer necessary to determine if the code works correctly because there are already tests in place to ensure just that.
One step at a time, nothing more & nothing less!
Another exciting feature of TDD is the more or less veiled constraint that leads programmers to take smaller and smaller steps. In one of his famous articles, Uncle Bob reinforces the TDD process by formulating 3 simple laws:
You must write a failing test before you write any production code.
You must not write more of a test than is sufficient to fail or fail to compile.
You must not write more code than is sufficient to make the currently failing test pass.
TDD as a well-established engineering practice
Today TDD is no longer a novelty. There are many teams and developers who rely on this practice to ensure a sustainable pace in product development.
The initial learning curve may be more or less steep, but it cannot be ignored.
Objection your honor!
Another common objection to TDD is about writing a test first. The usual claim is that there are scenarios where writing tests first doesn’t make sense, others where it is very difficult, if not impossible.
On the fact that it is difficult -sometimes very difficult- this is also true: oftentimes the defendants here are the underlying code, too rigid to allow the introduction of tests, or the lack of tools.
However, both are solvable problems: with a little work, it is possible to facilitate the adoption of the practice with the consequent benefits.
Last updated