Monday, May 17, 2010

TDD - levels of insight

Test Driven Development (or Design) is a method of developing code where you first write small tests that express the requirements, it can either be requirements from the customer or product owner, or requirements the developers themselves deduce are needed of the product.

The idea is that by writing the tests first, the design of the code improves, because it will automatically become modular (writing tests for code that's not modular is much harder, if not impossible). The tests also increase your development speed, since running your suite of tests takes a much shorter time than starting up the application and manually testing everything. If you make a mistake somewhere when refactoring the code or writing a new feature, it will become obvious directly, since the tests will expose it, if it breaks any of the requirements.

But let's not go into the details of TDD, there are plenty of other sources that describe TDD much better than I ever could.

Instead, this blog post will be about a hypothesis I have.
I don't believe you can really study TDD and just get it. You have to try it out for yourself and become convinced by experiencing the benefits. You will notice that you can keep maintaining a project without losing speed and your code will be extendable.

So what is the hypothesis? Glad you asked!
Every developer will go through a series of levels of insight, with each level being closer to being a TDD master.

And here are the levels I've identified, based on anecdotal evidence consisting of my personal experience, and what I've observed in others.

#1 Obliviousness
As a fresh developer, it's obvious that at some point in your life, you didn't know about TDD. I'd also take a guess that it's common to start programming before starting to write tests. From the various educations I've been to and talked to others about, testing is not something that's introduced early in programming training.

Obliviousness simply means that you're unaware of TDD is a practice and its usefulness. I was unfortunately in this category for much too long, which I suspect is true for a lot of developers.

#2 Disregard
The next step is hearing about TDD and getting the initial thought: "Writing tests first? That sounds backwards!". Not only that, you may also think that is seems like a waste of time to spend a lot of time writing tests that will soon be obsolete anyway, or tests for things that have obvious failures "I'll obviously notice immediately when starting up if this breaks".

#3 Awareness
Level 3 is being aware of TDD and that it can be a useful tool, and not just a stupid overhead designed as support for bad developers.

The easiest way to get past level 2 onto level 3 is to work with someone who's already past it, who seems to be using it successfully.

"Hmm, that guy produces clean code and doesn't seem to introduce as many bugs as I do, I wonder why..." Deeper investigation may lead to the introduction of TDD.

This may inspire you to try out writing tests first (or just writing tests at all), but since you're unfamiliar with TDD to begin with, your code will be hard to test, and it will be a pain to write the tests. You'll spend a long time to write the test, and you'll become irritated. "Do I really gain anything from spending so much time writing tests instead of producing code? QA will find any bugs I produce anyway, better to spend the time later to bugfix it instead."

Unfortunately, this is a typical setback that some people fail to get past.

#4 Empirical
Level 4 is when you've tried TDD for such a long time that you're really convinced that it's the best way to develop.
To reach this level, you need to really have used for such a long time that you have started to reap the benefits.

You have may have done a simple refactoring or introduced a new feature when one of your oldest tests break, and you look into it. "Aha, of course I needed to consider that before I did this, no wonder it broke!".

This is when you'll start building up the confidence in your code. If you introduce some code change that will break something, your tests will catch it.

Writing good tests, and writing them before the code is hard, as is writing clean and modular code. Becoming good at TDD takes time and effort, but it also makes you a better developer and better designer. Suddenly all your code will have at least two use cases - the test code and the runtime code.

#5 Mastery
After having been in level 4 long enough, TDD will become second nature to you.
You would use TDD for all development with the insight that it drives good design and saves time. No aspect of code is too hard to write test driven for a master, not even the typical daunting tasks intimidates the TDD master: UI, database, network, et.c.

I personally am stuck in level 4 at the moment. Perhaps I'll stay there forever, but even so it's probably a good idea to keep striving to reach level 5. I do this by trying to embrace TDD in my development as much as I can, but how can I be sure that's enough? Perhaps some other insight is needed to step up to the next level.

If I find any answers to that, You can expect a follow up post.

1 comment:

Olle said...

I find this very very easy to be true

Post a Comment