The benefits of Test-Driven Development
Thursday, November 24, 2016 - Richard Brown
Test-Driven Development (TDD) is a fairly well established software development practice, with lots of companies (large, corporate companies as well as smaller software development houses and design agencies) advocating it. Despite this widespread adoption there is still resistance to it, from both software developers and managers, so for anyone not yet convinced, these are the five main reasons I use TDD.
This is the obvious one: doing TDD means that you have a suite of tests that can be run on demand to verify that the system under test is behaving correctly.
Automated tests should be run as part of a continuous integration process, and the software development team should be alerted to any test failure to allow it to be investigated and fixed straight away.
Good test names succinctly describe the behaviour being tested. The name of the class and method being tested should be avoided as these names may be changed in future; instead use plain English sentences that focus on what behaviour is being tested, not how the system under test is performing that behaviour.
Enables safe refactoring
Poorly designed, hard to understand code is a great hiding place for bugs and can be a maintenance headache. A small amount of time spent refactoring code to make it easier to understand and work with can lead to big long-term benefits, as making changes to the code base can be done more quickly and easily. Unit tests allow this refactoring to be done safely as they provide immediate feedback if the refactoring has introduced a bug. Plus, in my experience, having the safety net of unit tests makes it much more likely that developers will carry out the refactoring in the first place.
Drives a decoupled design
In order to unit test something (for example a class) we must be sure that the only behaviour being tested is in the class in question, so it must be decoupled from any dependencies it has. This means that, during the unit tests of a class, any other object on which it depends must be ‘stubbed out’ somehow. Dependency injection is a widely-used pattern to achieve this decoupling.
Allows developers to compartmentalise the system
Writing software is hard. Especially if you want that software to be maintainable, readable, scalable, secure, and all of the other things we aim for when starting out on a project. One of the things that makes writing software hard is the fact that we are often dealing with complex business processes, each with its own set of rules (and various edge cases). It is infeasible for developers to keep all of this information in their head at one time, and I would go so far as to say that reducing their ‘working set’ of information to a manageable size is the single most important thing a developer can do to tackle the complexity inherent in most software development projects. TDD allows the system to be compartmentalised as the developer can focus just on the unit being tested, reducing their working set to a single class, or at most a small set of interacting classes.
There a many more reasons, but in my opinion the five points above should be sufficient to persuade anyone to give it a try.
For the past two years, the majority of Audacia's new web development projects have been built on a stack of:
- ASP.NET Core RESTful API
- An Angular UI running within an ASP.NET Core project.