The first thing I want to cover in my "learning TDD" track is to not worry about writing seemingly meaningless or uninteresting code. First of all you never know what shape code will take in the future – the simplest of tests might help prevent a subtle bug. Secondly, it won't be long before you start to write more interesting code, so hang tight!
That said, for the first couple minutes I didn't even know HOW to start. I knew that I wanted to start with a core class in my domain (an Indicator). Indicators do all sorts of interesting stuff, but since I'm writing tests first, I don't even have an Indicator class! To solve that little problem, I wrote the only test that made sense:
[TestFixture]
public class IndicatorTest
{
[Test]
public void CanCreateIndicatorInstance()
{
Indicator indicator = new Indicator();
Assert.IsNotNull(indicator);
}
}Of course the code won't build. So I create a new class "Indicator" and make sure the default constructor is there. I know that in theory you're supposed to make the test fail - but making my constructor throw a fake exception for the same of making it fail doesn't seem worthwhile. It's entirely possible that I'll opt to go with only factories for my Indicator class, but for now, this is the quickest way to get started.
Next, I know that every Indicator will have an Name, so I write my next test:
[Test]
public void CanSetIndicatorName()
{
Indicator indicator = new Indicator();
Assert.IsNull(indicator.Name);
indicator.Name = "Test Indicator";
Assert.AreEqual("Test Indicator", indicator.Name);
}So I go into my Indicator class and create a straightforward
private _name field with a
public Name property. Two points here. I could have easily made the test fail, but figured the broken build was good enough. Also, I agree that a public field would be the simplest solution here, but that violates our coding standards.
The Indicator class has a number of similar properties, so I write similar tests for all the ones I know about. Admittedly it isn't particularly fun and it doesn't feel too productive, but it's only a couple minutes of my time. There's an urge inside of me pushing me to take a bigger leap, but I keep it in check.
That's it :) I know it isn't much, but I had such a hard time accepting this way of starting, I figured others might also. I promise things will quickly get more interesting (though I think next post I might take a little break and go over nANT and CruiseControl.NET).
On a side note, as much as people talk about the importance of unit tests when it comes to refactoring, I honestly see them as even more useful when working in a team. The CanSetIndicatorName test tells the other developers on the project that someone expects the Name property to be null and NOT string.Empty when a new instance is created. If anyone changes my field declaration to
_name = string.Empty, the test will fail and hopefully they'll think twice about their change, else risk breaking code somewhere they weren't away of.
Technorati Tags: Agile, TDD, .NET