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]

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
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)