There are many reasons to write tests for our software. Validation. Verification. Non-functional requirements testing. Catching mistakes. Identifying edge cases. Documenting defects. Being the first user of our own interface. But I think one reason to test ranks above all the others. Maintainability.
I have seen and heard about many projects that start off promisingly. Features are delivered quickly by a skilled development team. Managers and Executives realise they have a great team that can produce the goods and decide to double down on the product. The team is encouraged to move quicker, to deliver features in shorter and shorter time frames. To take on more ambitious goals. In order to keep up with this ever more demanding pace, the development team cut anything that is not required by the current push for features. This normally includes thorough automated testing.
The problem occurs sometime later, normally about 2 years into the project, when the managers realise it now takes their team much longer to implement new features. They have the same number of developers as before, they are working the same number of hours. So what’s wrong? The code has become so messy and unmaintainable that no one is confident making changes, so everything takes much longer. There is then much handwringing and pointing of fingers as to whose fault this lack of productivity is. Then the project is cancelled.
This is a build up of technical debt. By technical debt I mean: the business owes a debt to the development team. By borrowing from their future selves the business has decided that moving quickly now is worth more than it will cost to pay back the loan later, making more money overall. This is the same calculation businesses make when taking out monetary debt. When the business makes this decision consciously then it is their decision to make, and it will either work out or not as they press up against market forces. But when this decision is taken lightly, with either no thought to the consequences or when non-developers are dismissive of the implications being warned of by the development team, then the whole project can fail.
By building in to your process thorough automated testing with aggressive refactoring you can attempt to hold off this fate. A good suite of automated tests, that can be run easily by the whole development team allows you to add new features and refactor with confidence by showing that your changes didn’t break anything. By being able to run tests quickly and repeatably developers need to keep much less of the program in their heads when making changes, so that they can concentrate on the important changes they are trying to make. I don’t think I can over state this, tests are key to maintainability. If you don’t want your program or your business to be around in a years time, then you can take all the risks you want to move quickly and break things. If you want to maintain a steady pace of development without a gradual slow down, then you need to invest in testing.
Most professional developers now seem to now agree that tests are necessary. But one of the marks of a professional is that we stand up for what we think is in the best interests of our client. We need to do more of this.