![]() |
||
![]() |
![]() |
|
![]() |
It’s worth stating up-front one of the main principles behind TDD: despite its emphasis on tests, it isn’t primarily about testing. TDD is actually about designing.
Using TDD, you design code by writing code. While this sounds circular, it means that you write client test code that serves as both an example and a definition of what you want the object code to do. For example, if you were writing a hotel booking system, you would write tests for placing a booking, adding customer details, retrieving the details, and so on. More specifically, you write unit tests that test for the expected results of doing these things. So a unit test for placing a booking would involve placing the booking and then asserting that the booking was correctly placed in the system.
Knowing which tests to write is driven by the user stories (in XP) or the use cases (in ICONIX Process). As you’ll see later in this chapter, the sequence diagrams also play a large part in determining the tests to write.
Micro Testing |
TDD is about designing at a very low level using fine-grained tests. In fact, there’s a trend away from the term “unit testing” toward “micro testing.” “Unit testing” is considered a bit vague, because the test for a large and badly written unit might also be large and badly written. “Micro testing” is more descriptive, in that these tests are meant to be very small. |
Using TDD, as mentioned earlier, you’re designing at a few feet above ground level. While this is fine for some projects, most of the time you’ll need an additional design process that operates at a higher level. ICONIX Process is an ideal candidate for this.
There’s some potential crossover in that ICONIX Process takes us to a very low-level design using sequence diagrams (by this stage, the designer/programmer is really thinking in code). We’ll discuss how to splice the two processes at this level of crossover in Chapter 12.
TDD uses the YAGNI[2.] principle for adding (or, more important, leaving out) features to code at two levels: requirements and design. Requirements-related features are left out on the basis that they’re not needed now, so let’s add them later. In TDD, this process is taken literally. That is, if there isn’t a test to prove that something works, then we don’t write the code; we write the test first. Using this process, tests actually drive the design.[3.]
To demonstrate this, let’s launch straight into an example using “vanilla” TDD. As you’ll see, the process as applied here works but can be long-winded. In the next chapter, we’ll repeat the example using a more effective mix of up-front design and TDD.
[2.]YAGNI is an acronym for You Aren’t Gonna Need It. See http://c2.com/cgi/wiki?YouArentGonnaNeedIt.
[3.]By contrast, in ICONIX Process, use cases drive the design.
![]() |
||
![]() |
![]() |
|
![]() |