Test Driven Design vs. YAGNI

time to read 4 min | 726 words

From Steve Freeman:

There's an interesting exchange going on in the .Net world (actually, in the Israeli .Net TDD with Mocks world, which I imagine is about as small as a community gets).

I just love this sentence :-) And I really like this discussion. Eli has responded to me and Roy's posts. Let us see if I can make an articulate response.

In my previous post, I showed a case where a testing seam was useful for enabling change down the road (you can see the code itself below). Eli was quick to point YAGNI. I can see his point of view. The difference is that I feel that if I need to change the design to make it more testable, I am adding value, not substracting it.

It is Test Driven Design, and the purpose is to have low coupled design, not just to test the code. TypeMock is a powerful framework, but I think that using it to enable brute force testing is harming the design process. You get regression tests via TDD, sure, but that isn't the point. Otherwise the next big feature for xUnit would be integration to the bug tracking on test failures.

The point is that you end up with flexible, working code. Eli finishes he post with this question:

Quiz: Which is easier to maintain:

File.WriteAllText(filename, text);


using(TextWriter writer = IoC.Resolve<IFileWriterFactory>().Create(filename))

I am probably not the target audiance, I recently had to explain why I needed four levels of abstraction just to get user input. But for myself, the second snippet is easier to maintain. IFileWriteFactory has well defined roles with regards to transactability and relaiability. A class that contains the first snippet is doing more than it should, in my opinion. The moment that is starts doing too much, I lose the ability to track it. I look at the snippets above and consider them in the context of the entire application, and it makes sense. I wouldn't use the IoC one for a toy app, but I can't think of a situation where I would just use File.WriteAllText() except in the depth of the util library, where I can absolutely control it.

I think that the difference in opinion between Eli and me is rooted in whatever YAGNI is applicable to testing hooks. In my opinion it does not, since I cosider the decoupled design that is often the result of the TDD as a major benefit by itself, regardless of anything else. I am one of those that approach code with a finger already positioned over the delete key, but I care about extensability in a big way.

I was working with a team member today and I selected a bunch of code to make a point, which elicited the immediate response:
"Don't delete that!"

I probably have very different ideas about what extensible software is than most people, I would admit, but I have found that this approach means that I can respond to change more easily this way. I have seen black box systems, but I have yet to see a well design black box system. Such is possible (I may create one, just fo kicks), but it is very rarely the case.