Cockatoo Software

Test Driven Development

Published on 03 June, 2010 by Keith Pitty

When one considers the process for developing software, it may seem natural to envisage writing the software and then testing it. Indeed, traditionally, that was a typical approach. However, in more recent times, the practice of Test Driven Development has been maturing. Read on to discover why this approach actually makes sense.

A Moving Target

Earlier in my career I was schooled in an old-fashioned approach to testing software. It was a phased approach that was tied to the predominant “waterfall” process of the times. Typically, independent units of software were tested in isolation and then tests were performed to see how well those units functioned when they were integrated together. Testing the system as a whole followed and, finally, the users were given a chance to test and decide whether or not the software was acceptable.

Young software developers who have learnt their craft in an age when Test Driven Development (TDD) is, if not de rigeur, at least widely acknowledged as a good practice, would quickly see the problems with the traditional approach described above.

Suspending Disbelief

As a programmer, having developed some software, it is easy to be convinced that it will work.

In 2008 at Railsconf in Portland, Oregon, I was fortunate enough to hear Kent Beck give his keynote address. I had long been a fan of Kent’s work and listened to him reminisce about his early experiences of automated testing. For the uninitiated, automated testing is the practice of writing code that, when run, will test the software under development. Kent recalled the first time he was prompted to write an automated test. He had scoffed at the suggestion that the automated test would find any bugs. In his software? No way! However, when the test did reveal a bug, he had no alternative but to accept the truth.

Kent is credited with rediscovering test-first programming and went on to create the xUnit family of developer testing tools.

I think it is reasonable to say that Kent Beck is in the upper echelons of computer programmers. But, as he freely admits, he is human enough to make mistakes. Now picture the combination of programmers with lesser ability together with the traditional “waterfall” approach to testing. Imagine a bug being found in user acceptance testing. A programmer fixes the bug, but what then? What verification is done to ensure that as well as fixing the bug, the programmer has not introduced other bugs as side-effects? All the unit testing, integration testing and system testing that preceded user acceptance testing is not redone. There would never be enough time to perform all that manual testing!

TDD provides a way out of this trap. The fundamental idea is that before any software is written, an automated test is written first. Automated tests are accumulated into suites. If a bug is discovered, the first step is to write a test that exposes the bug. And then fix the bug by enabling this test, as well as all the pre-existing tests, to pass. In this way, the software becomes much more malleable to change.

Behaviour Driven Development

Hopefully by now I’ve given you an understanding of why Test-driven Development makes sense. Before concluding this article, I’d like to mention a related approach that has proven to be very useful. It is known as Behaviour Driven Design (BDD). This approach aims to allow the behaviour of a software feature to be described and then tested. BDD is still a test-driven approach. What distinguishes it is its emphasis on describing what the software should do in syntax that reads like English.

Ruby is my current programming language of choice so I’ll use that context to provide a couple of examples of testing frameworks that emphasise the BDD approach. For automated unit testing, I find that RSpec serves me well. And for using BDD to test software from an external viewpoint, I am an enthusiastic proponent of Cucumber.

Further Reading

Should you be interested in exploring this topic further, I recommend Martin Fowler’s description of xUnit as well as Kent Beck’s original paper about a simple testing framework.

Of course, you don’t have to program in Ruby to gain the benefits of TDD. There are many code-driven testing frameworks for a wide variety of programming languages.

Conclusion

So there you have it. It does make sense to think about what software should do and write automated tests before actually writing the software is intended to be used. One advantage of adopting TDD and BDD is that the software development team is then well placed to reap the benefits of Continuous Integration. But that’s another story.

Keith Pitty is the owner of Cockatoo Software Pty Limited. He has over 30 years of professional software development experience and has a passion for providing software solutions that help people. Away from computers he loves sport, especially cricket, golf and Australian Rules football.