Christopher Bennage

Sponsors

The Lounge

Wicked Cool Jobs

Syndication

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Solving Problems with TDD

I'm giving a talk on TDD at our local UG tonight, and under the influence of some recent posts here on devlicio.us, I just finished reworking my presentation. This post is an outline for the first half of my presentation.

The Problems

Code has entropy. That is over time it deteriorates. At least, that's the metaphor we developers like to use. What is really means is that the code becomes harder to maintain and extend as it is maintained and extended over time. Did you follow that? Our typical approach to maintaining and extending code causes the code to become fragile and rigid and thus harder to maintain and extend in the future.

There are three common difficulties that arise, maybe more, but I'm focusing on three:

  • Unchangeable Code
  • Unintelligible Code
  • Unnecessary Code

A portion of code becomes unchangeable when its deeply entwined and entangled with other portions of code that have different responsibilities. You can't change method X because we really don't know what that will do to Y and Z.

Code can become unintelligible for lots of reasons: abbreviated names, circuitous logic, enormous methods, confusion of responsibilities, use of php☺, etc.

Finally, unnecessary code is code that is not used by the system. It can be vestigial, or as often happens, it can be the result of feature anticipation. We thought this was going to be needed in the app, so...

The Solutions

There are some generally accepted solutions to these three problems.

In the case of unchangeable code, we can apply such patterns as Separation of Concerns (SoC) and the Single Responsibility Principle (SRP). For addressing unintelligible code, we have a number of techniques such as thoughtful comments, explicit naming, SRP again, etc. Finally, for unnecessary code we have the old axiom of You Ain't Gonna Need It.

Okay, so we know how to solve the problems. Or least, we know how to mediate them. So what? What does that have to do with TDD?

My proposition is this: solutions are without value unless they are applied.

Additionally, when a problem occurs over time, the solution must be applied over time.

The Analogy

I just started going to the gym. It's been about a decade since I did that, but I'm back. For the past several years however, I have been preaching to certain family members the value of exercise and healthy diet. I knew the benefits: stress reduction, longevity, improved sleeping, and just plain feeling better. However, I wasn't really doing either.

I had the problem and I believed in the solution and, in fact, I made attempts to employ the solution. Ultimately, I was unsuccessful. That is, until I committed to go to the gym three days week at a set time and with a workout buddy.

My point is this, we are human beings and despite being smart we frequently revert to doing "the easiest thing". Therefore, we ought to set up some sort of framework of methodology or discipline where the easiest thing is actually what we want to do.

Additionally, I have to keep on going to gym. For as long as I want to be fit, I will need to exercise. In the same way, for as long as I want my code to fit I will need to apply good principles.

TDD as a Discipline

I will argue that TDD is a discipline that enables the application of the solutions outlined above. Perhaps you apply those solution naturally. Perhaps you can benchmark 200lbs because of your genetic disposition. Bully for you. Go ahead and skip the rest.

Let's examine a few essentials of TDD and see if they really address the problems we outlined.

Test First

I'm an advocate of automated testing in general. However, I do think that writing your tests first yields additional value. Primarily, it helps you discover your ideal API. In other words, you can design your API up front such that it is more intuitive. More intuitive means easier to understand.

Secondly, testing first helps you identify dependencies early. You quickly discover that class X will need a Y and so you are forced to create seams in the application at the onset. This encourages SoC and SRP.

Testing Units

It took me a long time to understand the "unit" part of unit testing. The idea is that you decompose your problem into units, and deal with the problem one unit at a time. You could call this "test just one thing". Okay, well what is "one thing"? That is hard to tell and comes with experience. Nevertheless, the practice of trying to decompose a problem and identifying units leads you back to SoC and SRP again.

Just Enough Code

Another tenet of TDD is to write only enough code to pass the test. Our natural instinct is to anticipate. It is part of what we are as developer, and it is not a bad thing. However, like many strengths, it can become a weakness. By constraining ourselves to a single problem at a time we will end up with less code. It also forces us to be conscious about our anticipation and to ask if a given scenario is really necessary.

Conclusion

I know that there is much contention over the actual value of TDD as a practice, and I am not going to force it on anyone (unless I hire you and now you are warned). However, I have found it to be a useful discipline for helping me to overcome common problems and because of that I encourage it's use.


Posted 11-06-2008 3:03 PM by Christopher Bennage

[Advertisement]

Comments

JoshG wrote re: Solving Problems with TDD
on 11-06-2008 5:37 PM
Nice! As an additional point, Domain Driven Design (Eric Evans) contains many principles that address all those code issues, but in particular Unintelligible Code, as we bring the vocabulary in the code alongside the business. If they call it an SKU, we don't model a Product. It's much easier to find what has to change when the business makes a change.
Christopher Bennage wrote re: Solving Problems with TDD
on 11-06-2008 9:48 PM

@JoshG thanks. Evan's book has been a big influence on my thinking as well. I was actually pitching Ubiquitous Language in the post-presentation conversations.

Dew Drop - November 7, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - November 7, 2008 | Alvin Ashcraft's Morning Dew
on 11-07-2008 8:38 AM

Pingback from  Dew Drop - November 7, 2008 | Alvin Ashcraft's Morning Dew

Emanuele DelBono wrote re: Solving Problems with TDD
on 11-07-2008 11:11 AM
I talk about related argument about TDD for problem solving just yesterday in my blog. If you want you can read it here: http://blog.codiceplastico.com/?p=162 TDD save my life
Christopher Bennage wrote re: Solving Problems with TDD
on 11-07-2008 11:22 AM

@Emanuele That's a good success story. Interestingly, some of the critical conversation after my presentation last night was regarding the efficiencies of solutions produced by TDD.

The criticism was that TDD can enable solutions that are wasteful. I think you nailed it though when you said "it met the customer's requirements". That's the key, what is the business value, what is the return on the time spent implementing the solution?

Emanuele DelBono wrote re: Solving Problems with TDD
on 11-07-2008 12:56 PM
@Christopher The time spent to build the solution using TDD is the same if not minor to the time needed to build it without tests. And from now I have the tests that help me on every new requirements of modifications. Consider also that without tests you spend a lot of time with the debugger and in these type of application is very hard to find bug!
Arjan`s World » LINKBLOG for November 7, 2008 wrote Arjan`s World » LINKBLOG for November 7, 2008
on 11-07-2008 3:31 PM

Pingback from  Arjan`s World    » LINKBLOG for November 7, 2008

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)

CodeBetter.Com