The various meanings of TDD

Update: more on this here and here, and Jim has a whole article on this here.

Now that I'm having some real time to write something I thought I'd try to write down my thoughts starting all the way back from JAOO and what I learned from it. Specifically the whole notion of TDD, and what does TDD mean to different people.

"TDD will deteriorate your design". that was the sentence I heard coming out from the mouth of Jim Coplien, a speaker at JAOO and a well respected guru in the software industry in many levels. I tried to grasp what he was saying again, so I repeated the sentence in my head. "TDD will deteriorate your design, so don't do it". Yes. I heard correctly. 

It was lined throughout the discussion Jim was having about Scrum and Architecture and was just one small point he made which he didn't even take the time to review fully. "Will deteriorate your design" and then nothing. Someone from the crowd of about 400 challenged him and Jim was starting to quote a couple of research papers which I don't have a link to so I have not read them.  Jim was kind enough to leave a comment on my previous post about JAOO but that did not include any links to those research papers. Could anyone leave a comment here with a link to them?

When Jim walked out of the hall I started talking to him for what ended up to be about 40 minutes of intense rhetorical debate of what does TDD really mean and then what benefit if at all does it have. I'll weave points from that in but first I need to say that I realized something: TDD is not a clear enough concept so people see it in different light depending on who you ask.

What are the possible meanings of TDD?

  • 1) Test Driven Development: the idea of writing your code in a test first manner. You may already have an existing design in place.
  • 2) Test Oriented Development: Having unit tests of integration tests in your code and write them out either before or after our write the code. Your code has lots of tests. You recognize the value of tests but you don't necessarily write them before you write the code. Design probably exists before you write the code
  • 3) Test Driven Design(the eXtreme Programming way):  The idea of using a test-first approach as a fully fledged design technique, where tests are a bonus but the idea is to drive full design from little to no design whatsoever. You design as you go.
  • 4) Test Driven Development and Design: using the test-first technique to drive new code and changes, while also allowing it to change and evolve your design as an added bonus. You may already have some design in place before starting to code, but it could very well change because the tests point out various smells.

It's important to realize the distinction between these four perceived notions of what TDD could mean because when Jim said "don't do TDD" he meant one of these. Unfortunately he didn't really explain which one he meant (maybe he hadn't realized they exist) so the message he gave out was essentially "Whatever you think TDD is, don't do it".

Which of these notions corresponds to what you think TDD is? which do you think I would choose?

From my conversations with Jim it would seem that he think about TDD as option number 3 - Test Driven Design. He was saying that if you do it the XP was where you let the tests drive all of your architecture you're bound to get into trouble so leave it alone. I'm leaving the argument of whether pure test driven design works or not  for later. Right now I want to make sure we're all on the same line.

If you're going to say TDD doesn't work - explain what you mean by TDD or be prepared to be bombarded with questions which you may feel have no connection with what you're talking about.  

My notion of TDD is #4 - Test Driven development which can also help evolve and better your design. I always start with some sort of design, even a basic one. Sometimes so basic it's all in my head or on a whiteboard, but there's some skeleton there I use to guide me. I also let it change if my tests point out that there might be some testability problem here and there. I'm not saying pure Test Driven Design does not work. I'm sure it works for people, and I'm sure if failed others.

The Alpha Architect and Test Driven Design

One interesting thing that came up in that conversation (which many people assembled and chipped in with their on thoughts in) was the idea of the "Alpha Architect". There seemed to be agreement that the people who can do pure test driven design (like Ron Jefferies) probably already hold all the design they need in their head, so they don't get why other people can't do the same thing. These "Alpha Architects" are pretty unique and perhaps live in some sort of bubble where things like TDDesign feel much easier and simpler.  I'm not sure that's the case but I can understand the idea and willing to agree that it's possible.

So, is Test Driven Design only good for teams with Alpha Architects in them? not sure, but it's a question worth asking.

So, is TDD Bad?

Are the rest of the notions of TDD bad? In our talks Jim agreed that unit tests or integration tests might not be a bad idea after all as long as they don't kill your design. When he said "but I was saying TDD kills design I said it because that's what people think TDD is!". The only reply to that is that by telling them that you are only reinforcing their belief that they know what TDD is, and not even questioning their assumption (or yours) that it could be a good thing.

I think that TDDAD(Development and Design) is a good thing. I'd love for my assumptions to be challenged. I'm still waiting to get the links to the two research articles mentioned.

your comments are appreciated.

possible topics for the future posts:

  • Things I realized about XUnit from talking to Brad and Jim
  • BDD vagueness and tooling
  • Ruby coolness
  • The ALT.NET Conference roundup
Published Monday, October 08, 2007 9:49 PM by RoyOsherove

Comments

Monday, October 08, 2007 11:46 PM by Bil Simser

# re: The various meanings of TDD

I'm in agreement with you on what TDD means (at least that's what it means to me). I start systems with a bit of a design. Whether it's something in my head (if I'm the driver in a pair in which I'll communicate the design through tests to my pair) or something on a whiteboard, cocktail napkin or notes jotted down in a text file. As for TDD being bad, I suppose that's true if you're purely driving a design out of tests and you couldn't architect yourself out of a paper bag. For the rest of us, I think it's a fabulous tool for communication, collaboration, and evolution of a design.

Tuesday, October 09, 2007 1:34 AM by Mike Liddell

# re: The various meanings of TDD

Related (possibly identical) to #2 is Test-conscious design and architecture => Every design and architecture should have testability as one of the fundamental requirements.  This applies to Alpha-architects and as-you-go-Architects equally.  In its full form, it should realy be *-conscious-design,

where * =

 Testability

 Security

 Performance

 Scalability

 Maintainability

 Simplicity

A related term (possible identical) to #1 is Test-driven-Programming.  This is not 'design' although it might have a flow-back effect as syntax etc crystalises while coding.  This is where I personally feel that TDD actually works.  For this, the idea is

1. you have a solid architecture/design in mind

2. you have a reasonable idea of the type of code you are about to produce (rough form, syntax, hierarchies, core fragments), but its not a formal UML or anything crazy.

3. you have an overriding desire to not produce any lines of code that are not unit-tested, either due to philosophy, or awareness that your planned code is risky/complex/likely to have issues.

If all of 1,2,3 are true, then TDP is great.  you write tests, you write code, you get green lights, you get near-100% coverage and its all happy and well-behaved.  Refactoring during TDP s truly refactoring rather than 'wow I had no idea I was going about this backwards, I better rewrite everything', which is clearly not normal refactoring.  

I personally do not like the concept of TDD meaning test-driven-DESIGN where, for some reason, the syntactical form of a unit test is supposed to pre-date thinking about the problem.

Tuesday, October 09, 2007 4:25 AM by Ian Cooper

# re: The various meanings of TDD

Hi Roy,

I think one of the issues with Agile is that a lot of people do not have experience of using  waterfall via a methodology, like SSADM, and thus do not understand what agile was reacting against. Instead they compare agile's statements to some ersatz, light weight, in-house agile methodology (which is, in a sense where agile grew from).

I think this problem is as prevalent in the agile community as outside it.

So when XP talks about not doing 'big-design up front' it is reacting to the multi-month design phases that characterized waterfall where in a 9 month project, the first 3 months would be spent doing design.

I do not believe that Agile intends that you do not have an idea of where you are heading with your design. Crystal expects there to be a design produced from its Exploratory 360 phase. I think that XP expects there to be an idea of  design, because I think that the reason for whole team involvement in the Planning Game is to have a design conversation amidst the team while they begin implementing.

But with Agile these activities take hours or perhaps days, not months. We learn about our destination, and some key way markers on the journey, but we don't necessarily know the whole route.

The problem is that we have lost the context in which Agile was formed, and many exponents are mouthing the mantras, without understanding the reason for them. That lack of understanding is, I think, damaging to Agile, and people need to step back and ask why more often.

Tuesday, October 09, 2007 7:53 AM by Kent Boogaart

# re: The various meanings of TDD

In turn, I think you'd have to define design. To me, design is thought and collaboration - not a piece of paper. As you hint, you can start coding with a design solely in your head. But the point is the design is there, even if not physically manifested.

But people who start a development without any thought or collaboration (design) deserve all the pain they get. TDD does not a *substitute* for design, it is a tool that can be used to *aid* design. That brings us full circle back to Jim's statement about it deteriorating design. I would also love to read the cited papers.

Tuesday, October 09, 2007 8:39 AM by Justin Livesay

# re: The various meanings of TDD

A TDD approach to evolving design from scratch is a demanding exercise in OO design skills. It is a hard thing to do without the proper requisite knowledge in recognizing code smells and how to refactor to better solutions.

However, it is also one of the best ways I have encountered to sharpen those skills. Studying design patterns and refactorings builds up the potential for design improvement and TDD instills it into practice. Doing one without the other is ineffective.

For developers without a high level of skill in these areas, I would question how effective prescribed designs are really going to be anyway. Perhaps TDD will deteriorate your design in these cases, but thats likely a symptom of poor design in the first place.

Tuesday, October 09, 2007 10:23 AM by Matt

# re: The various meanings of TDD

Excellent post.  I'm a bit horrified that someone speaking as an authority would lay out a blanket statement like "don't do TDD".  

I guess I hadn't really thought of what TDD means to me, but I'd say #3 or #4 is probably accurate.  And I completely, 100% disagree with Jim's view.  There is zero doubt in my mind that TDD has made me a better, more productive developer and has improved the design of my projects.

Tuesday, October 09, 2007 12:55 PM by Anthony Williams

# re: The various meanings of TDD

I agree with you that TDD means that you write tests first, and evolve your design as you go. I find that this works well. I may have to change my design as the application grows, but that's expected, and refactoring the code to fit the new design is never a big deal. That said, sometimes I design the whole thing on paper before writing any code --- I like to have some idea where I'm going, even if the destination changes on the way, as I spot improvements during development.

In my experience, TDD certainly doesn't kill my designs --- TDD makes my designs better.

PS. Ron will be upset that you added an extra "e" in the middle of his surname.

Wednesday, October 10, 2007 4:12 AM by DotNetKicks.com

# The various meanings of TDD

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Wednesday, October 10, 2007 6:33 AM by Halldor

# re: The various meanings of TDD

Hi

According to what many are talking about, many say that BDD or Behavior Driven Development is more reliable than TDD and gives better production and code, you´re basically giving people what they want. If you have a good time again you can blog about that too, would be fun to see the results and comparison of the two

Tuesday, October 16, 2007 10:14 PM by Marty Nelson

# re: The various meanings of TDD

Isn't the original agile answer to BUF design to do TDD <i>plus</i> "shared system metaphore"?  Invoking a combination of "Individuals and interactions over processes and tools" and "Working software over comprehensive documentation."

Also, if you're not writing the test first, how do you know when the design is "done"?

# Scott&#8217;s Blog &raquo; Multiple meanings of test-driven development

Pingback from  Scott&#8217;s Blog &raquo; Multiple meanings of test-driven development

Monday, November 05, 2007 5:31 PM by My first practical experience with TDD | Nerdd.dk

# My first practical experience with TDD | Nerdd.dk

Pingback from  My first practical experience with TDD | Nerdd.dk

Monday, November 26, 2007 12:11 PM by Braxton Perry

# re: The various meanings of TDD

I think one thing missing from the discussion is the granularity or degree of TDD.

In SQL, we all know that 5th NF is better than 3rd NF. But 5th is rarely practical.

I think you have good test in place "just "before or "just" after a design and get the benifiets.

Also TDD'ing database and GUI can be impracticle. Stick to TDD'ing the unique code you wrote.