HTML and CSS Reference
in Section 2.4, Benefits of Test-Driven Development, once we have gotten to know
the process itself better.
The test-driven development process is an iterative process where each iteration
consists of the following four steps:
Write a test
Run tests; watch the new test fail
Make the test pass
Refactor to remove duplication
In each iteration the test is the specification. Once enough production code has
been written to make the test pass, we are done, and we may refactor the code to
remove duplication and/or improve the design, as long as the tests still pass.
Even though there is no Big Design Up Front when doing TDD, we must invest
time in some design before launching a TDD session. Design will not appear out
of nowhere, and without any up front design at all, how will you even know how
to write the first test? Once we have gathered enough knowledge to formulate a
test, writing the test itself is an act of design. We are specifying how a certain piece
of code needs to behave in certain circumstances, how responsibility is delegated
between components of the system, and how they will integrate with each other.
Throughout this topic we will work through several examples of test-driven code
in practice, seeing some examples on what kind of up front investment is required
in different scenarios.
The iterations in TDD are short, typically only a few minutes, if that. It is
important to stay focused and keep in mind what phase we are in. Whenever we
spot something in the code that needs to change, or some feature that is missing, we
make a note of it and finish the iteration before dealing with it. Many developers,
including myself, keep a simple to do list for those kind of observations. Before
starting a new iteration, we pick a task from the to do list. The to do list may be a
simple sheet of paper, or something digital. It doesn't really matter; the important
thing is that new items can be quickly and painlessly added. Personally, I use Emacs
org-mode to keep to do files for all of my projects. This makes sense because I spend
my entire day working in Emacs, and accessing the to do list is a simple key binding
away. An entry in the to do list may be something small, such as “throw an error
for missing arguments,” or something more complex that can be broken down into
several tests later.