TDD – a better option for developers with ADD

So I’m back on the unit testing kick again.  In my defense, I do spend an awful lot of time thinking about them – either feeling guilty about not writing them, or thinking about them as I code them, then (optimistically making it sound like I write tests first) or thinking about the testability of a particular piece of code as I write it.  They are dear to my heart, in a strange kind of way.  Part of me loathes them – being a pale approximations of actual applications behaviour,  and the rest of me has only ever found them useful.  Either proving my code, having decisions I (or those before me) have made confirmed to be conscious or driving my design.  And that’s what I want to talk about.  Test Driven Development.

I’m fairly convinced that most people don’t have a firm grip on what Test Driven Development is.  Before we begin properly, I’d like to mention that I have actually read the book by Kent Beck.  Including the code examples!

Now that my credentials are clearly proven and sufficient, I’d like to start by saying that test-first and test-driven development are not the same thing. That’s where most people get it wrong. Both are Good Things, but I favour test-driven development for a couple of significant reasons.

Read more of this post

The Third Virtue

Unit Testing is boring and tedious.  This is not just a hyperbolic opening line with the thinly veiled intent of grabbing the reader’s attention.  The only times I can remember enjoying writing a unit test were cases where there was a short setup to a not-quite-trivial problem, leading to the application crashing, such that writing out a unit test is not only less annoying than a manual scenario, but in some small way, I feel like I’m giving the buggy code the finger by not letting it inflict its full potential for disaster.  I am only four, after all.

Now is when the Hubris comes out.  How can we improve this situation?  Unit testing is not only recommended, but is indeed part of being a software professional.  If code you’ve written doesn’t have some automated testing around it, I would like you to have at least considered it, and made the conscious decision not to, for a good reason.  Otherwise, you’re not doing your job properly.  It’s really that simple.

Read more of this post

The Second Virtue

As I discussed in my previous post Unit Testing is a Good Thing.  But once you’ve got enough testware, it starts to become a burden.  At that point, most companies worth their salt will invest in some high-spec hardware on which to run the continuous integration system.  This is seen as an opportunity to increase productivity by knowing earlier when some code is wrong.  This is sound logic.  But this doesn’t solve the problem for the developers trying to run the tests before they check in said breakage.  Larry Wall’s second virtue, Impatience, starts to come into play quite significantly here.

I have personally spent a lot of time and extended effort into making a large, complicated C code base build and test as accurately and quickly as possible.  And even then, with the build spread across eight 12-core blade servers, each with 32 Gb of RAM, we manage to build and test in around 20 minutes.  Now, even though the developers have high-spec’d four core boxes, they still can’t even come close to the raw power of eight server-class machines, even if they can borrow some of their CPU time with distcc.  We’ve therefore created a partial build which attempts to build just enough to catch around 90% of the errors with only a small portion of the required effort and even that can take upwards of half an hour.

Where, then, does the balance sit?  How much do we require gets built for every change before every developer is slowed down enough such that it actually becomes faster to just check in and hope (for a given value of hope).  And anyway, how many people are updating so often, without taking note of the readily available state of the build, such that they’re feeling the pain of the build being broken.

Read more of this post

The First Virtue

Sigh.  Oops, I did it again.  And I don’t mean quoting an ageing pop star.  I broke the build.  I checked in something I thought was right – it was a simple search and replace, and I chose the wrong constant.  I was replacing a hard-coded value with an enum – doing thankless cleanup which will one day allow us to re-order this collection (ok, it’s way too risky for us to actually do that, but at the very least, we’re gaining a descriptive index, telling us what we’re modifying).  The good news?  We have unit tests that caught it – our code coverage is still producing numbers that we justify with a “legacy code base” but it is good enough to catch errors like this.  The bad news?  I’m on holiday having a relaxing week to myself, several hours drive away from the nearest computer with said code checked out and one of my colleagues has emailed me to inform me of my dump and run.  I didn’t want to leave any half-baked tasks lying about when I was on leave, so I was doing some “safe” janitorial work.  When it came time to check in, I exhibited the first of Larry Wall’s three virtues – Laziness.

We’ve all done it.  We will all continue to do it.  Why are we kidding ourselves that there is some magical pixie dust in the form of the latest testing trend that will save us from ourselves?  Test Driven Development is a wonderful idea – I heartily encourage it.  I even try to do it myself sometimes, because it really works!  So why don’t I do it all the time?  Why don’t I even Unit Test all the time?  That, Detective, is the right question.

Read more of this post