Most people who know about Test Driven Development have heard the phrase, "Red, Green, Refactor". When it comes to actual implementation of this technique there seems to be a bit of a disagreement. By following the rules of RGR we all agree that we start by writing a failing test (Red), we write the code to make the test pass (Green), and then we make the code better and remove duplication (Refactor). The point of contention I hear about most often is in the Red stage. Some people say to write the failing test before writing any code. Some people say that you can make a skeleton of the code and write the test for that.
In practice I tend to agree with the people that make the skeleton code first. I really just don't like having the compiler error be how my test fails. What I do instead is create the code I am going to test and have it throw a NotImplementedException. This lets me make sure the test is failing so I am sure to flesh out the code.
Now I can certainly see reasons to do both. That is just what I prefer. One interesting problem which can arise from doing my method is the following. Say that I am going to create a new method on a class, so I create the method and write the failing test. Perhaps this is a non-tested project I am working on, so only the new stuff is tested. I write my code and everything passes now. But I've created a new bug. How?
I am kind of cheating here because there is a compiler warning. Since not everyone treats compiler warnings as errors it is certainly possible to have missed this problem. Here is some example code including an extra base class I didn't mention yet.
class Program { static void Main(string[] args) { Foo myFoo = new Foo(); myFoo.Bar(); } } internal class BaseFoo { public void Bar() { Console.WriteLine("Base Bar!!"); } } internal class Foo : BaseFoo { public void Bar() { Console.WriteLine("Bar!!"); } }
So now if I create a method called Bar without realizing there was already one on the parent class I will be hiding the parent one and breaking the existing logic. Since the old code isn't tested I will not know about it. If I had written a test before the code, I would have noticed something odd when the compiler didn't throw an error.
I think it is an interesting debate. Not very important, but interesting. Perhaps people have some more reasons why it should be one way or the other.
Comments