TDD != No Debugging

Earlier this week Scott Bellware wrote a great entry about meaningful tests in a TDD process. I highly suggest you read it. Go. Now. Then come back. I'll wait. OK, ready? Good.

In his post Scott makes the following statement about using the debugger with regards to TDD:

“Debugging code is a slow, time consuming process.  Time spent in a debugger is sloth time.  You might be thinking that you're perfectly effective in a debugger and that you don't have any objections to doing code validation in a debugger rather than in a well-factored unit test.  This is merely an assumption fed by how habituated you are to using a debugger.  Without having a TDD practice, you have no basis of comparison for how ineffective debugging is compared to writing well-factored unit tests for well-factored code.“

Now, I'm sure Scott isn't advising to stop using the debugger completely when writing code, but that paragraph does comes close to crossing that line. In fact, I think some people would be lead to believe that he is in fact saying just that. I bring this up because this isn't the first time I've heard statements similar to this.

Having read Scott's blog for some time, I'm completely in agreement that a skilled TDD practitioner is more effective writing higher quality software than a non-TDD person. However, that does not mean the skilled TDD practitioner completely abandons using the debugger. The skilled TDD practitioner just happens to NOT use the debugger to drive his tests. That's the key point to take away. Just because you practice TDD does not mean you should forget your knowledge of how to use the debugger.

Print | posted on Thursday, November 24, 2005 7:02 AM

Feedback

# re: TDD != No Debugging

left by Jim Holmes at 11/24/2005 9:04 AM
Good post, Dave. I'd contacted one of the TDD superstars for an article I'm writing on debugging in Visual Studio. He didn't have time to respond for the article, but said "I can give you the TDD-contrarian's answer: 'What are you doing in the debugger, anyway?'" He seemed only half-serious, but that struck me as a flawed mindset regardless of the serious-quotient.

# re: TDD != No Debugging

left by Frans Bouma at 11/24/2005 9:13 AM
" I'm completely in agreement that a skilled TDD practitioner is more effective writing higher quality software than a non-TDD person"
I don't see why this is a fact. It can be the unittests help a seasoned TDD developer write code which can be of a higher quality, but how you say it implies that if you use TDD you will write code of a higher quality.

I really disagree with that, for the simple fact that any good quality software package from the past which isn't developed with TDD shows that without TDD you also can write high quality code, and thus TDD isn't necessarily required to write high-quality code.

That doesn't mean TDD doesn't HELP, the techniques used in TDD CAN help you with writing good software. However the quality of the software depends on the person writing it: a lousy programmer with TDD is still a lousy programmer and will write lousy, crappy code.

# re: TDD != No Debugging

left by Brian H Prince at 11/24/2005 8:21 PM
Britany and I both agree with you on this. I have seen many developers become proficient in TDD, and stop using old fashion test harnesses and the debugger. This leads to more productivity now, and more assurance things don't break in the future.

Scott's viewpoint I think comes from the 'zealotry' that often accompanies TDD/agile type practices.

-bhp

# re: TDD != No Debugging

left by Dave at 11/25/2005 2:00 AM
Frans - Point taken. Before TDD there were certainly people who could write high quality software. No argument there. And I also agree that even without TDD today you can definitely write quality software. It's just that in my opinion (and that's all it is) TDD inhibits one's ability to write quality software even moreso.

# re: TDD != No Debugging

left by Scott Bellware at 11/26/2005 12:11 PM
Frans,

If you equate quality with good factoring that leads to an easier testing experience, then I believe that the implementation and design patterns drawn out of TDD leads to higher quality code.

To wit, a number of teams at Microsoft are investigating TDD to arrive at EVEN BETTER code. Microsoft has certainly produced a lot of successful apps, but I know from personal experience that integrating with some of the Microsoft apps leads to a less than stellar experience as soon as my code touches their models.

Office is a great product, but it can certainly be better. The poor factoring of the Office code becomes quite clear when you dive in to do Office automation. I haven’t used VSTO 2.0 yet, but I know that I am significantly hampered by the Office model when I attempt to build testability into Office integration code.

Had the Office apps been built from a TDD perspective through test-driven design, the factoring of the product would have been much truer to the inherent optimal factoring of that codebase.

As for crappy coders... I've watched a number of crappy coders become reasonably good coders after having come under the auspices of TDD practices. I don't know if they became great coders because TDD enablement engagements don't last that long.

I’ve seen no other method that systematically clarifies those things that bad coders need to learn in order to become good coders, and that then offers a systematic program of constant feedback to support the transition.

# re: TDD != No Debugging

left by Scott Bellware at 11/26/2005 12:21 PM
Jim,

The response, "What are you doing in the debugger, anyway?" is pretty typical feedback from the TDD perspective. There are always times when the debugger comes in handy, but you would find under TDD that the stuff you typically use the debugger for is solved by developer tests and well-factored code.

Ultimately, you begin to understand in retrospect that the debugger is often used by non-TDD coders as a validation mechanism to verify that code branches when it’s supposed to, and that calculations done deep in an execution path are done correctly.

TDD drives out branching, reducing cyclomatic complexity, and flattens execution path depth.

TDD practitioners don’t simply avoid the debugger, we fundamentally impact software design and factoring so that using the debugger for software validation isn’t necessary.

We do this because using the debugger as a validation tool isn’t as expedient as using tests in this role. This really only holds water when using tests against code that is shaped by the design pressures inherent in TDD.

# re: TDD != No Debugging

left by Scott Bellware at 11/26/2005 12:32 PM
Dave,

I'm absolutely not suggesting that developers forget how to use the debugger, or that they avoid using it in the appropriate circumstances.

The point I’m making is that when you create the kinds of tests and kinds of designs inherent in TDD, the need to use the debugger diminishes drastically. This is a good thing, because comparatively, the productivity achieved in doing TDD and the productivity levels inherent in depending on the debugger are significantly different.

Based on my own experiences, and the experiences of many TDD practitioners, the TDD development style is much faster than a style that depends on using a debugger.

I will say this as plainly as possible… when I see folks who are learning TDD spend what I consider too much time in the debugger, it is because they haven’t yet grasped the design imperatives inherent in TDD.

Just because a developer goes through the motions of writing tests first doesn’t mean that he has any reasonable depth of understanding of TDD. Writing tests first merely means that a developer knows how to tie his shoes. He has yet to learn to walk, then run, then fly.

During the transition phase, you might find yourself in the debugger just as much as you would using less contemporary development approaches. Being in a transition phase and accepting that a transition phase even exists is one of the biggest challenges to individual developers to cross the chasm to the software design aspects of TDD – which are ultimately the whole point of TDD.

# re: TDD != No Debugging

left by Scott Bellware at 11/26/2005 1:14 PM
Brian,

I think you at once corroborated the ideas expressed in the quote from my blog post and refuted them in the space of a single comment. Since we’re just calling names then, allow me to counter your use of “zealotry” with “ignorance” :)

When I’m talking about TDD, I’m not merely talking about doing test-first programming and having test coverage – these are arguably mere QA activities. I’m talking about gaining a cognitive foothold on the designs that greatly amplify the opportunities for reuse harvesting; the designs that drastically reduce cyclomatic complexity thus making test fixtures much more readable and maintainable; the designs that open up opportunities for the kind of loose coupling that SOA depends on; the designs that allow for the replacement of far too much state testing with more simplified interaction and cohesion testing using dynamic mock object proxies, and ultimately to application architectures based on IoC and enabled at runtime by dependency injection tools like Spring and StructureMap.

I’m making a broad assumption here that you aren’t familiar with this extent of the software design value system that emerges from TDD. Non-familiarity with this stuff would likely lead most folks to look at TDD practices and come away with words like “zealotry” on their tongues. There are a number of VB 6 developers who look at OO and have had the same response – and they may be right… in the context of the kinds of applications that VB 6 was created to support. Nonetheless, any survey of TDD that doesn’t include an understanding of TDD’s inherent software design goals is a survey that takes TDD out of context and likely leads to a number of invalid assumptions about TDD that stem from a limited perspective.

TDD is a whole school of thought driving software designs that support the contemporary demands of software development. Many of TDD’s practices support ideas and goals that most developers simply haven’t internalized yet.

TDD isn’t a tool – you can’t plug it in to your IDE and go to town. TDD is a practice and a set of skills. You’ve gotta spend - in my experience - a whole lot of time with it before the big picture is clear. The transition form waterfall development practices to TDD is even more involved than the transition from procedural programming to object-oriented programming, and it implies some of the same human behavioral pitfalls. Especially those that arise from a developer assuming that he “gets” OO only to realize a year later that he had not but a cursory understanding of the most obvious facets of the practice.

In this regard, I take your bandying of a word like “zealotry” toward a fundamental and well-known TDD reality as an indication of a shallow perspective of TDD and a limited amount of practice and study in the area.

I welcome a much deeper dialog regarding TDD once we have dispensed with the ad hominem aspects of the interchange. I would be very interested in understanding how TDD applies to the use of BizTalk and the business integration code that is typically more amenable to integration tests rather than the developer unit tests that I have been focusing on in my writings on TDD, whether developer TDD practices are even applicable at the service bus, and whether other agile testing practices and tools might be more amenable to this kind of work.
Comments have been closed on this topic.