November 6, 2011

...Learn TDD with Codemanship

The Test-driven Development Maturity Model

I spend a lot of time talking to people about Test-driven Development, and I've learned over the years to translate what folk tell me about their TDD experiences based on my own experiences of then doing TDD with them (or watching them do it.)

On a whim, and with a large slice of cynical irony, I've constructed my own Test-driven Development Maturity Model (TDDMM), and mapped that on to stuff people tell me about TDD.

You can use this guide to accurately assess someone's TDD experience duing similar conversations. Or you can print it off and wipe your arse with it. Both options are about as useful.

Before I begin, I should make myself absolutely clear: I'm not berating people who don't do TDD. (Though I'll be interested to know what you are doing instead that would produce similarly clean, reliable code that can be quickly and cheaply re-tested throughout development.) This is a maturity model aimed at people who claim to have done TDD. Before you ask, it's a sort of joke. Well, maybe.

Level 0 - Doesn't Know What TDD Actually Is

You'd be surprised how many folk say they've done TDD, but then go on to demonstrate that they probably haven't even read the Wikipedia entry on it. They'll say things like "We do TDD, but we're not purists about it." "Purist", in software development, is secret code for "someone who actually does it at all". They'll often go on to say that, in their "pragmatic" approach (more secret code), they write unit tests after they've written the code. Test-Driven Development. The clue's in the name, folks.

Level 1 - Knows What It Is, But Has Obviously Never Done It

These folks tend to be academics (either literally, or of a type). They're well-read enough to know the basics of TDD, but further probing often reveals that they lack any practical experience. The giveaway tends to be a lack of technical detail in the recounting of their experiences, coupled with a vague and handwavy flavour to it all. They will often speak with a deceptive air of authority, but we must remember that we risk taking sex tips from monks if we heed their advice. One must be careful, though, because people who have a lot of TDD experience can also come across this way. If you're not sure, then 5 minutes with them, you and a laptop will remove any doubt.

Level 2 - Tried TDD. Made My Fingers Bleed.

Getting started with TDD is a bit like learning to play the tuba. It takes quite a while to get pleasing results out of it, and most people don't have that kind of patience. They can often turn into the worst kind of TDD haters, taking every opportunity to poo-poo it in public. But no amount of public poo-poo can disguise the fact that their dislike ultimately stems from their inability to get anything approaching a musical sound out of the end of it during the few days or weeks they tried to learn it. Sad fact is, most people who try to learn TDD give up within 3 months, while they're still climbing its steep learning curve. But rather than admit they never made it to the summit, they prefer to tell people not to bother because "the view from up there is rubbish".

Level 3 - Doing TDD. Well, kind of.

In the pyramid of TDDMM, Level 3-ers are genuinely way ahead of the curve. 9/10 who claim to have done TDD are Levels 0-2. The kinds of noises I hear from these hardy folk tend to fall into the category of "but it's sooooo hard". Often, they'll talk about the overhead of all those bloody automated tests. They take ages to run. They're brittle and hard to change. They're slowing us down. Etc etc.

Danger, Will Robinson! This stage in the development of your TDD ability is make-or-break. I hear too many stories about teams ditching TDD, and ditching their test suites, to make the going "easier". And it will feel like that for a wee while - like throwing the engine out of the plane when it's losing altitude. Chances are, their TDD is a little unbalanced. It may be 99% RED LIGHT-GREEN LIGHT and only 1% REFACTOR. Moving to Level 4 requires an epiphany. Namely that test code is production code, too. And all the programming and design disciplines that apply to production code need to be applied to test code. Oh, and it turns out that the whole "refactoring" thing is really rather more important than we thought. In fact, it's the secret sauce of sustainable test-driven development.

Level 4 - Doing TDD. And Living The Dream. Well, sort of.

Demonstrably, people who've been doing TDD for years and who've hacked through the dense undergrowth of brittle tests, incomprehensible tests, slow tests, highly-coupled untestable designs, over-reliance on mocks and etc etc, tend to find that they actually go faster when they do TDD, and they can sustain that pace on the same code base for years.

Here's the thing. Even to us old lags, who've been doing it since before anyone thought to call it "Test-driven Development", TDD never gets what you might call "easy". There's a battle-scarred world-weariness about the Level 4 TDD-ers. They might not speak of it as enthusiastically or with the fresh-faced idealism of an early Level 3-er, but underneath it all there's a resigned air of "well, of course we do TDD", and a recognisable rolling of the eyes when they hear people talk about "pragmatic TDD", or about how "TDD doesn't work" or about how "TDD slows you down".

Level B - People Who Speak To The Dead

On an entirely perpendicular maturity scale are those very experienced practitioners who go around making bizarre and unsubstantiated claims about programmers who "don't need to do test-driven development", as if they've somehow transcended the need for it.

Now, I'll be the first to admit that you can achieve the same kinds of results without writing your tests first. But, y'know, it's the darndest thing; in order to achieve those results we tend to end up doing things that look a heck of a lot like test-driven development. Take, for example, Formal Methods. Whether it's expressed as tests, or in some more general form, any techniques I've seen that produce TDD-like results always start with a testable specification and always involve a process of verifying that the code we're writing satisfies that specification, either by traditional testing, or through other kinds of testing - like guided inspections, symbolic execution, model checking, proofs of correctness etc. And if our goal is to get the feedback from this testing a soon as possible, then we need to be able to perform those tests as the code's being written. It is true that some programmers are sooooooo clever, they can see that their code will work just by reading it, and this may reduce the need for things like unit tests in that first instance.

But I've yet to meet a programmer who was genuinely soooooooooooooooooooooooooooooooo clever, they could re-read, and therefore re-test all of their code several times a day to make sure they haven't inadvertantly broken something. Being clever, as testing techniques go, doesn't scale well.

But let's assume that such a rare beast exists - a unicorn among programmers. We'd better hope that this unicorn is immortal. And omnipresent. Otherwise, what happens when someone less brilliant and clever tries to change their code? You can be the safest driver in the world, but you'll still need to wear a seatbelt and have insurance. Because unless every driver is as safe as you, you're going to need it.

The trail of automated tests I leave behind me is more there for future developers who may work on that code than for me, though it makes my life so much easier, too. They estimate that software costs 7 times as much to maintain as it does to write in the first place. if leaving behind a suite of good automated tests reduced that to 6 or less, than time writing and maintaining those tests is time well-spent.

And all the hard evidence we have available to us suggests that's the case. On the other hand, there's no good evidence - not one shred of it - to support the existence of these mythical unicorn programmers who don't need to do TDD (or anything resembling TDD).

Programmers who claim to be so good they don't need to do TDD have a special place reserved in my vision of Hell that is the Test-driven Development Maturity Model.


Posted 6 years, 4 months ago on November 6, 2011