Menu

What is TDD? What is Test Driven Development?

Episode 60 - 02 Nov 2016

Here's a non-technical introduction to TDD. We'll be digging into Unit Tests, test isolation and the myserious world of mocking.

Key take-aways on Unit Tests:

  • Writing Unit Tests for existing code can be difficult
  • A Unit Test is a test of a component in isolation
  • In order to test is isolation, any external dependencies must be mocked
  • An example of something that is frequently "mocked" is a database connection
  • Units Tests tend to be very fast to run.

Key take-aways on Test Driven Development:

  • It's an iterative process: write a small test... write just enough code to get the test to pass. Rinse and repeat.
  • The tests and the code that the tests "cover" are born and grow together. They are intertwined.

Remember to grab your FREE TDD vs BDD Cheat Sheet

What is Test Driven Development?

Aka TDD?

I'm glad you asked!

Unit Tests... can be hard

First things first.

If we're going to talk about Test Driven Development, we first need to talk about the particular type of test that underlies TDD:

Unit Tests.

I first came across Unit Testing in about 2008.

By that point, I'd been developing full time for a few years.

I thought I had it down.

But I found writing unit tests to be hard. Damn hard. 10x harder than writing code.

Depressing.

I eventually discovered that it wasn't my fault.

Much of the stuff that I thought was impossible to test ....

... really WAS impossible to test.

It wasn't me after all!

Why were the tests impossible to write?

I was trying - and failing - to write a test for something that...

... wasn't like a spark plug.

Test Isolation

Remember in the last episode we talked about testing the gap of the spark plug?

That's a perfect example of a Unit Test.

Another perfect example would be a test of its resistance.

With the right equipment, we could even perform a unit test to confirm that it sparks.

All of these tests are possible because there's something special about a spark plug

It's... TESTABLE!

By design, it can be removed from the engine.

It's one of the few things in the world that has a (more or less) standardised tool for removing it.

My guess is that spark plugs weren't designed specifically to be testable.

I think it's probably the case that spark plugs were designed to be replaceable

and test-ability came as a very useful side effect.

It's been my experience that things rarely evolve naturally to be replaceable/testable.

They are replaceable/testable by design. Or not at all.

Nowhere is this more true than with software.

I can say with a high level of confidence, that if your codebase does not have unit tests,

then your codebase consists largely of UNTESTABLE code.

Test Driven Development

Which brings us nicely on to Test Driven Development.

Test Driven Development, as the name suggests, is a process by which the tests are written BEFORE the code.

This doesn't mean writing all of the tests and then writing all of the code.

it's more subtle than that.

You start by writing just one test. A very small test.

Then you write some code. Just enough code to get the test to pass.

Then you write another small test.

Rinse and repeat.

The code and the tests are born and grow together.

The test-ability of the code is "built in".

Mocking

Writing Unit Tests is easier for new code than for existing code.

But that's not to say that it's trivial.

There is a complication.

The key to a unit test is to test the "unit" in isolation.

If you saw the previous episode, I performed the following test:

  • I removed the plug cap,
  • unscrewed the spark plug,
  • plugged it back into the plug cap
  • and operated the kick starter.

This was a test for spark, but it was NOT a Unit Test.

Because it's not a test of the spark plug in isolation.

(It's actually a test of a whole host of components working together.)

A Unit Test is possible. It just needs some additional equipment.

This device takes the place of the battery and a whole array of electrical equipment.

The device is assumed to be working,

so if there's no spark, we know that it's the spark plug that's at fault.

The software equivalent of providing this "additional equipment" is called "faking" or "mocking".

Mock example

To give you a quick example:

if I write a function to determine if the current year is a leap year,

I'm going to want to mock the date.

That way I can feed in a whole series of dates

And check/test that I get the right result.

Alas, mocking isn't always so easy.

There are many real world cases where creating suitable "mocks" can be tricky and time consuming.

But the payback - and this is a key advantage of unit testing -

is that when a test fails, you know exactly WHAT has failed.

Too hard?

If this all sounds like too much like hard work, you may be interested to learn about Behaviour Driven Development.

Which, by happy coincidence, is the subject of our very next episode.