Most people agree that Unit Tests are a good idea, and most developers try to write them (with varying degrees of success). But the challenge of creating Unit Tests for existing projects can be incredibly daunting to developers.
Many people may not see the need, if an area of code has been working for quite some time then why introduce tests which will take a lot of time and (if you need to refactor to make them work) introduce risk in an area? When I wrote about the value of Unit Tests back in 2015 I postulated that the value of these small executable is not in finding bugs, it’s in preventing bugs in the future.
Unit Testing, unlike exploratory is not about finding issues with existing code, it’s about reinforcing and documenting (through executable code) exactly how each function, class, and property should behave in particular circumstances. If you understand this then you’ll see that the value of Unit Tests does not diminish with an established solution (even if most of the teething bugs have already been worked out). In fact it makes your existing code bases much easier to safely maintain!
So the question becomes how and where do we start?
I’m currently working on an application which has in excess of five million lines of code in it. Some parts are new and some date back to the project’s inception. Writing a full set of tests for the entire application is a monumental (and I have to admit largely pointless) exercise.
What we need to do is look at the areas which are most in flux. If Unit Tests are a technique for helping to protect our software against unexpected change then the areas where they deliver the most benefit are the areas of code which change frequently.
We’re engineers, not psychics (at least I’m not) so use metrics. Look at your Source Control history and see which classes are subject to frequent change (both bug fixes and feature work applies). Target your Unit Tests here, use the 80:20 rule and target your efforts in the right place. One of my favourite sayings applies here… how do you eat an elephant? A little at a time!
Slowly, little by little the classes which see the most changes will stabilise and you’ll introduce less bugs when expanding them or fixing existing defects.
These are my thoughts, do you have any experiences breaking down huge applications into Unit Tested code? How did you do it?