An Introduction to Test Driven Development
Test Driven Development has certainly stood the test of time, the process has been around for decades with NASA's Project Mercury perhaps being the earliest recorded use of TDD/test first techniques in software development. In more recent history we've seen it emerging prominently up and out of the eXtreme Programming movement of the late 90's, championed by Kent Beck and others.
So what is TDD?
Put simply, it's the software development process of writing a test first, followed by just enough code to satisfy the test, then a final but important step of re-factoring.
Not only does this process prove that the emerging code correctly satisfies tests (essentially that the code is fit for purpose) but it aids developers in thinking about the design of the code they write. It keeps the focus on small iterative steps that collectively build solid functionality and ultimately result in working software.
In addition, tests by their very nature, provide valuable documentation. The tests grow to form a catalogue of how the software should behave and also capture the intent of the developer. Add to this the bonus that tests travel with the software providing invaluable regression feedback during subsequent phases of development or maintenance and TDD certainly stacks up as a convincing recipe for success.
These benefits and more, are well documented in white papers such as IBM's study into its own sustained use of the process over a 5 year period which concluded that any perceived productivity loss (the additional time taken to write the tests) was far outweighed by improved software quality. The report stops short of an absolute claim of improved code maintainability over its lifetime but it certainly alludes to it - add to this the plethora of blog posts (this one included!), podcasts and numerous books extolling the virtues of TDD and it's hard to imagine why it's not simply the ubiquitous modus operandi!
Hold on a minute, is TDD always appropriate?
OK, so before we get carried away in a naive flush of enthusiasm and broad brush strokes, when is TDD not appropriate? In my opinion, it boils down to a single important point:
Always use the right engineering process for the thing you're doing.
Are you building a disposable prototype in rapid short iterations for some quick feedback? Some would argue that tests would still be useful but clearly you're not going to get all the benefit, your prototype will be discarded, you won't have ongoing maintenance where a suite of tests would prove invaluable against regression.
Building a complex product that will likely be years in development and will go on to be maintained by numerous developers in the future?
Building a popup site that'll only be live for a week?
Clearly, different tasks and projects call for different approaches and we must remain flexible, there's no room for a one size fits all mentality in software development!
I sense the aspiration...
When I talk to developers who have yet to try TDD, I sense the aspiration is there. Ask anyone who cares about what they do for a living if they'd like to improve the result of their work and you will most definitely hear an affirmative response. On the other hand, there are always those who feel they don't need Test Driven Development, "It's a waste of time, I don't need tests to prove my code works, I'm a professional, I've been doing this years...". On balance, I genuinely believe no-one sits down with the intent of writing rubbish, hard to understand, spaghetti or broken code (unless they're practicing MDD - Mortgage Driven Development). It just happens, line by line, day by day, bug fix by bug fix. It happens... a lot. And it's called entropy.
I recently stumbled across a recording of Kent Beck's keynote address at RailsConf 2008, he told a series of three stories, three stories about "ideas with impact" he'd played a part in over the previous 20 years, he introduced the section about TDD in this way:
"[developing testing is about] developers taking responsibility for the quality of their code, testing really isn't the point, the point here is about responsibility, when you say it's done... is it done? Can you go to sleep at night knowing the software that you've finished today works and will help and isn't going to take anything away from people, that's the point of developer testing..."
I found something about the frankness here engaging, it certainly makes me want to become a better developer.
Is the business convinced?
I've already touched on the perceived productivity loss incurred by adopting TDD, reluctance might stem from purely financial considerations because time, after all, is money.
There are also without doubt, development companies and clients alike who firmly believe that clicking around a site or desktop/mobile application is sufficient testing in itself!
Whilst it can be hard challenging entrenched opinions and long established ways of working, we are fortunate to have at hand the historical data of those who've trodden the path before us, those who have gone to great lengths to capture the detail and measure the success or otherwise of this process.
Microsoft for example, concluded a study into three of its development teams with the following opening paragraph:
"Our experiences and distilled lessons learned, all point to the fact that TDD seems to be applicable in various domains and can significantly reduce the defect density of developed software without significant productivity reduction of the development team. Additionally, since an important aspect of TDD is the creation of test assets—unit, functional, and integration tests. Future releases of these products, as they continue using TDD, will also experience low defect densities due to the use of these test assets"
Hard evidence is hard to ignore.
Perhaps you've already weighed the evidence and feel it's time to introduce TDD to your development teams or maybe you're a freelance developer who's wanting to step up! In subsequent blog posts I'll be offering tips and advice on how you can get started, I'll also be sharing how we use TDD techniques at Code Enigma!
1. "On the Sustained Use of a Test-Driven Development Practice at IBM" was published in 2007, it reports on IBM's case study into TDD whilst developing JavaPOS device drivers - http://agile2007.agilealliance.org/downloads/proceedings/006_On%20the%20...
2. "Realizing quality improvement through test driven development: results and experiences of four industrial teams" was published in 2008, it reports on TDD practices used by three teams at Microsoft whilst developing Windows, MSN and Visual Studio and also makes reference to the IBM case study previously mentioned - http://research.microsoft.com/en-us/groups/ese/nagappan_tdd.pdf