Thursday, July 13, 2006

A Test-Driven Development Manifesto

I have been asked to codify my beliefs and practices when using the Test-Driven Development methodology. One of the things that I like about this methodology is that it is fairly easy to describe.
I believe that to practice Test-Driven Development is to do the following things in the following order:
1. Transform requirements for your task into unit tests.
2. Verify that all of these new tests fail (since none of the requirements have been met yet).
3. Start designing my solution.
4. As I add functionality that wasn’t described in step 1, I will add unit tests first.
5. I am done with my task when all of my unit tests pass.
6. Maintenance: Whenever a defect is logged against my code, start by reproducing it with a unit test. The defect is fixed when the unit test passes! (this also ensures that we don’t re-introduce the same defect later.
Ideally, all execution paths in my code will be covered by a unit test. Again, this is a huge win for maintenance since I can write new features and refactor existing code without being afraid of breaking any existing features or defects (refactoring is complete and successful when all of my unit tests pass).

2 Comments:

Blogger Eric said...

I just got some excellent questions about this post:

Question
What do you do with all the broken tests at build time? Do you leave them broken or mark them Ignored?

Answer
Ideally we should never be checking in broken unit tests, however there are several cases I can think of where we have had to use the Ignore attribute:
* Under a time constraint where we know that the unit test is failing because it no longer reflects the expected functionality. It is preferred that we update the unit test, but sometimes there just isn’t time.
Or
* After requirements have changed and we are unsure as to whether the case being tested is valid.
Or
* You are in-progress on a class and test fixture and would like to check in your changes before they are complete (basically a “save to source control”). In this case, I would Ignore my test fixture with a comment that this logic is “in progress”.

Question
Do you stub the classes the test must call? Isn't that starting to design code prior to writing the test?

Answer
I like to do a sort of “Just in time” unit testing. I’ll try to start by writing a few unit tests that kind of box the problem. Then I start writing “real” code. Every time I come to a branch in the code (an if statement, a switch statement, or a new public method – usually for handling an event), I will stub the code and then write unit tests that cover all branches before I fill in the stub.

11:46 AM  
Blogger Adron said...

More entries please.

9:26 PM  

Post a Comment

<< Home