Test Driven Development, not always to the extreme.

TDD is great stuff. It turns traditional programming on it’s head, back to front, upside down and says, rather than writing some code then doing a bunch of manual tests on it, tweaking it’s robustness as you do more testing, begin with the end state in mind.

I’m a firm believer of doing this with everything. It’s one of the 7 Habits of Effective People (Stephen R Covey), and it works in every aspect i’ve ever applied it. Just asking yourself ‘What am I trying to achieve?’ or ‘What’s important here?’ gives you instant focus, and it’s proven that when you’re aiming for a specific goal or outcome the human mind is more keenly focused and energised – some food for thought.

So TDD. Great. Do it all the time. Only ever do TDD. Right. Easier said than done, although ?-Unit testing frameworks have come a long way thanks to Kent Beck et. al. But TDD 100% of the time?

Although it’s possible, especially with greenfields projects setup the right way, I can’t imagine it being the norm. Kind of like pair programming. People say ‘you should pair 100% of the time’. I disagree. Like anything it’s finding a sweet spot that works for your team, your project, your culture. It may be 30% it may be 80%. It depends 🙂

Give me an example, I hear you ask, of where I *wouldn’t* want to use TDD? Two things come to mind. Startups and spikes (in agile). I almost consider them the same thing. Many startups begin with a horrible codebase. Why? Because most startups don’t start with best practices, they start as a spike on a PC somewhere.

Many startups readily admit this that after 3 months of production life, they have a technical debt. As the dust settles and their core market becomes clearer, they may shift to another codebase or refine their development to formally add tests, QA and processes into their development. It doesn’t start out that way!

How many tests are enough? J.B. Rainsberger alluded to the fact that you can write millions of tests, if they are not useful (testing frameworks not business logic, testing redundant code paths) then they will not serve you, you will serve them. Like anything else, tests add coupling to your code. It’s a fact. You need to accept this, and you should. There are only 2 situations where you should need to modify a test.

a) you have broken a test because you’ve modified code that tests executes such that it fails (you’ve created a regression bug).

b) you have modified the business logic on purpose because of a change in requirements. In this case, the test needs to be updated. This also allows you to verify you are in-fact changing the behaviour correctly.

You write tests to give you confidence about your changes. If you write good tests, they will not get in your way all the time.

I have been writing alot of tests in Jasmine lately. Jasmine is a beautiful DSL in javascript, similiar to RSpec, which allows you to write unit and integration in javascript which can interact with AJAX and the DOM. Before using this, we relied heavily on selenium tests to test the client side of the web application. TOO SLOW. TOO BRITTLE. Yes, selenium tests have their place, as the 10-20% of tests to test full functionality.

Jasmine really is awesome, 12 months ago I would never have imagined I can mock and stub AJAX calls, mock responses from the server side and test DOM interactions in multiple browsers. All of our tests run in Firefox, Chrome and IE. For this reason, I believe it is more important than selenium tests, since it works on a lower level than selenium, the tests execute orders of magnitude faster and they still physically run in a browser. Well done pivotal labs.


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