Mark is a graph advocate and field engineer for Neo Technology, the company behind the Neo4j graph database. As a field engineer, Mark helps customers embrace graph data and Neo4j building sophisticated solutions to challenging data problems. When he's not with customers Mark is a developer on Neo4j and writes his experiences of being a graphista on a popular blog at He tweets at @markhneedham. Mark is a DZone MVB and is not an employee of DZone and has posted 544 posts at DZone. You can read more from them at their website. View Full User Profile

TDD: Big Leaps and Small Steps

  • submit to reddit

About a month ago or so Gary Bernhardt wrote a post showing how to get started with TDD and while the post is quite interesting, several comments on the post pointed out that he had jumped from iteratively solving the problem straight to the solution with his final step.

Something which I've noticed while solving algorithmic problems in couple of different functional programming languages is that the test driven approach doesn't work so well for these types of problems.

Dan North points out something similar in an OreDev presentation where he talks about writing a BDD framework in Clojure.

To paraphrase:

If you can't explain to me where this approach breaks down then you don't know it well enough. You're trying to sell a silver bullet.

The classic failure mode for iterative development is the big algorithm case. That's about dancing with the code and massaging it until all the test cases pass.

Uncle Bob also points this out while referring to the way we develop code around the UI:

There is a lot of coding that goes into a Velocity template. But to use TDD for those templates would be absurd. The problem is that I’m not at all sure what I want a page to look like. I need the freedom to fiddle around with the formatting and the structure until everything is just the way I want it. Trying to do that fiddling with TDD is futile. Once I have the page the way I like it, then I’ll write some tests that make sure the templates work as written.

I think the common theme is that TDD works pretty well when we have a rough idea of where we intend to go with the code but we just don't know the exact path yet. We can take small steps and incrementally work out exactly how we're going to get there.

When we don't really know how to solve the problem – which more often than not seems to be the case with algorithmic type problems – then at some stage we will take a big leap from being nowhere near a working solution to the working solution.

In those cases I think it still makes sense to have some automated tests both to act as regression to ensure we don't break the code and to tell us when we've written the algorithm correctly.

An example of a problem where TDD doesn't work that well is solving the traveling salesman problem.

In this case the solution to the problem is the implementation of an algorithm and it's pretty difficult to get there unless you actually know the algorithm.

During that dojo Julio actually spent some time working on the problem a different way – by implementing the algorithm directly – and he managed to get much further than we did.

It seems to me that perhaps this explains why although TDD is a useful design technique it's not the only one that we should look to use.

When we have worked out where we are driving a design then TDD can be quite a useful tool for working incrementally towards that but it's no substitute for taking the time to think about what exactly we're trying to solve.


Published at DZone with permission of Mark Needham, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)



Peter Esbensen replied on Thu, 2009/12/10 - 4:25pm

Not sure I understand. Can you explain a little more?

For example, you can find lots of datasets with known solutions on the web for the Travelling Salesman problem. Why not write tests using those datasets? When they pass, you know your implementation is good.

The fibonacci example you reference IS pretty strange . . . if somebody knew the problem well enough to write the testcases, why would they proceed to write the algorithm in such a naive manner? Maybe that's your point. But I would argue that's just a confusing example. I still think it's a nice practice to write the testcases first, whether its fibonacci or some other algorithm problem.

Rainer Eschen replied on Sat, 2009/12/12 - 9:57am

I also have some problems to understand. A test shall have a look at the result and describe the requirements. This is what I understand how e.g. BDD is done. So, why is this dependent on the design of the implementation. Maybe you should switch from a botton-up to a top-down test writing approach if it is not clear to you how to implement it.

Beth99 Zhu replied on Mon, 2009/12/14 - 1:05am

Do you like business? Do you want earn more money? we are worldgoldshop seller, we sell many kinds of products.If you looking for an honest, reliable business partner, please contact us. We are the best choice for you.You can browse our web:

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.