Test-Driven Development
What does testing have to do with class design? Everything! Test-driven development (TDD) is a methodology where you actually write tests before you write the classes. The goal is to write the classes so that they pass the tests. In Chapter 16, "Testing, Deployment, and Code Management," we'll cover TDD in more detail, but for the sake of design, we'll discuss it briefly here.In test-driven development, you write tests that satisfy a business requirement. Going back to our car example, we would write a test to unlock the car before we've written a single line in our Car class. Naturally, this test won't even compile because the Car class doesn't yet exist. However, by writing the test in this manner, we can concentrate on how the class we're going to write should be structured. Our business requirement is that we want to be able to unlock the car, so it makes sense that we should have an Unlock() method. Listing 3.7 shows a fragment of test code that puts the emphasis on the design of our future Car class, not its implementation.
Listing 3.7. Test code fragment
This example is ridiculously simple, but imagine for a moment that you need to do something more complex. We had an earlier discussion about whether it makes more sense to have method-driven code or use a combination of properties and methods (or even use static methods). By writing a test that simulates some real use for a class, we take some of the guesswork out of the class definition process.Another benefit of this development style is the avoidance of "scope creep" or "feature creep," where we write more than we need because it seems like a good idea at the time. By defining our class through the use of tests derived from business requirements, we don't have to guess what to include. We only need to develop the code that satisfies the tests.After you've written your tests, you can "stub out" the class with just enough code to indicate the class's structure. At that point, your tests (and your class) will compile, but naturally your tests will still fail. You'll continue to write code until your tests pass. This methodology can give you great confidence that your code will work as you expect because hopefully you've created unbiased tests that account for most situations before you've even written the class itself.Testing is performed using free tools like NUnit, which we'll cover in Chapter 16.
Car myCar = new Car();
car.Unlock();
Assert.IsFalse(car.Locked);