tags:

views:

89

answers:

2

Which is the first test I should write when following the TDD guidelines? A test for the whole system or for the smallest core method?

Example: A project should read a CSV and convert it to XML. My first test should be:

  1. Take a CSV (input) and the corresponding XML (expected) and checking if the application does the conversion correctly (Assert.AreEqual(expected, actual)) ?

  2. Take a CSV (input) and the corresponding memory representation (expected) and check if it is parsed correctly (Assert.AreEqual(expected, actual)) ?

the second option represents one of the methods that are used to achieve the whole goal, which is represented by the first option.

+5  A: 

You have to first have an idea of the big picture, but once you have the idea -- start small. Decide what the first thing (small) is that you would have to do. So, for instance, say you want to have a method that given a line of input, returns a collection of the individual values as strings. The first test I would write would take a string of values: "1,2,3" and expect an array of strings { "1", "2", "3" }. I'd write more tests that vary the number and type of the different values. Add a test for an empty string, etc. Obviously, I don't know what you exact expectations are so just consider the above as one possible way, not the way to do what you want.

I'd slowly build up the functionality with the desired end result in mind, letting the tests drive the overall design of the application. I don't think you'll be successful with TDD if you start big because you have to make a leap from nothing to the full functionality in one step. TDD is about taking small incremental steps toward the eventual goal, letting the design and code grow as you go.

tvanfosson
+3  A: 

Whichever happens to be easier. Sometimes it's better to start at top level when you can mock the lower levels. At other times it's better to start at a low level and go up from there.

I think that often times I start from near the top (for example the UI model), especially if I don't have a clear picture of what the lower levels should be like. But when I have a clear picture of the overall architecture and the system is big, then I might start from a lower level component which I know that will be needed.

In this particular example, "A project should read a CSV and convert it to XML", I would start with a test than converts an empty CSV file (actually just an in-memory string) to an empty list of some in-memory representation. Doing one conversion at a time has the benefit of separating the responsibilities, and you will better know that in which side of the conversion the bugs are.

That should be trivial enough test to get a good start. After that you can write a test for converting a CSV file with one row and one column. Depending on how it goes on from that - if it proves to be too hard to work top-down - then you might decide to build some smaller parts bottom-up, or to mock some of the lower level components.

Esko Luontola
You have a well reasoned approach. I like the flexibility.
David Robbins