TDD Pt 1

Test-Driven-Development (TDD) is a concept that I have always struggled to get my head around. Testing before you have anything to test does not seem to make any sense. However I have spent the last few weeks working in an environment where TDD is used, and am now completely enlightened. Testing is clarification that you have achieved what you set out to achieve. Before you can do start anything you have to have a goal / aim of where you want to get to, so it follows that this can be a test.

By writing the test before the code you ensure that:

  1. You achieve the outcome you are aiming to achieve
  2. You keep it as simple as possible

So the first point is obvious. If the test is written saying what you want to achieve, then you can easily prove you have done so. A test that passes is the emotional certainty that you (the developer) have done your job correctly. The test then acts as documentation, which can also be traced back to the initial requirement that was supplied by the analyst. Thus no time wasted on additional documentation.

The second point is perhaps more important still and is what makes TDD so elegant and neat. It ensures that the developers only write the code that is needed to pass the test. They do not need to spend ages thinking about what else the system should do, which means they can spend longer thinking about how to write the functionality that is required in the best possible way.

Moreover it means simplified design. You only add as much design to a system as you need to pass the current tests with clean code. Thus there is no commitment to any design until the code calls for it. So the design fits the code rather than vice-versa.

Indeed Kent Beck emphasises that there are only two simple rules to TDD:

  • Write new code only if an automated test fails
  • Eliminate duplication

This means you design organically as the running code provides feedback between decisions. You can rapidly respond to small changes. This is why it works well with object-oriented designs – it means you can build small blocks with the certainty that everything before works. Designs are made up of highly cohesive, loosely coupled components.

It is only a short step between this and Domain Driven Design (DDD). I am almost confused about the difference between the two. Surely if TDD is done properly they are the same thing? Certainly the line is blurred. I will follow this up with a piece on DDD (which I am pretty certain is the best and most logical way to develop anything).

How does TDD actually work?

So you have to write a new piece of functionality. There are three steps for this:

  1. Work out what you want to achieve
  2. Write a test for it
  3. Write the code

There is more than one interpretation of this. Following the agile development pattern, each of these steps can be carried out by different roles. The analysts work out what the functionality needs to do. The testers translate this into a test. The developers write the code to pass the test. However Beck stresses the importance of having the same person write the tests as the code.

This is evident when we draw comparisons between the steps above and Beck’s Red / Green / Refactor “mantra” of TDD. According to this, TDD involves the following steps:

  • Red – Write a test that fails (and may not even compile) as you have not yet written the function
  • Green – Write whatever code is needed to pass the test
  • Refactor – Get rid of any duplication that you had to put in to get the test to pass

Here the whole testing / development process is done by the developer. This is partly to make things quicker – if everything is broken down into small, discrete pieces of functionality then you do not want to be waiting around for someone else to write tests for you. This then frees up the testers to do proper QA work after the function has been written.

The fact that there is TDD is open to interpretations can only be a good thing as it means that it can be adapted to best suit the needs of your team. Indeed Beck admits that it is a slightly fuzzy concept as it is aware of the gap between decision and feedback during programming, and being able to control that gap.

There are certain programming tasks that cannot be driven solely by tests, for example security software (where human judgement is also needed) and subtle concurrency problems that cannot be duplicated by running the code.

However it seems unlikely that I will be attempting tasks such as the above anytime soon, so until that happens, I will be doing my doing my utmost to write tests before I attempt to write any code.

Advertisements

About RNewstead

I am learning every day. Sometimes I worry there are too many interesting things in the world and not enough time.
This entry was posted in Agile, Development, Test and tagged , , . Bookmark the permalink.

One Response to TDD Pt 1

  1. powderach says:

    So I had a chat with one of the devs on my team about this and he (quite rightly) pointed out that this post reads like it was written by someone who had not used TDD v.much. That is the case, and is something I am struggling with at the moment as I try to work out the best way to do things. Another aspect that was pointed out was that I have overlooked the middle D – that it is test DRIVEN development. So the test should drive the way you write the code. I guess the reason I have neglected this is that it is the hardest part to get my head round when coming at this for the first time. Hopefully with more experience I will be able to improve upon this post!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s