Unit Testing is a Tool, Not a Task
All too often I run into development projects that have little to no unit tests. Unit testing is seen as an extra task that takes up too much of the developer’s time.
Surprisingly, it seems that the open source community and individual developers have no problems adding unit tests. It is the companies and big teams that tend to neglect them.
I think a lot of this has stemmed from the fact that many companies establish major processes around unit tests. Code coverage must be 95%. All pull requests must have unit tests. These types of regulations are well-meaning, and I’d argue necessary. But if developers don’t understand why they are unit testing, then it’s more of a chore than the tool that it was always meant to be.
The Nails Keeping Everything Together
When building a house, construction workers use nails to setup the framework. Nails are a necessary tool to create your typical house. No construction worker in his or her right mind would lay out all of the scaffolding, build everything up and just assume the structure would stay up. Moreover, they certainly wouldn’t add the nails after building the house. Not only could this risk knocking the whole house down, but they could miss certain sections of the house completely.
I think of this every time a piece of code is merged to production without unit tests, or when developers claim they don’t have time to add unit tests. Not having time to add unit tests is equivalent to not having time to add nails. It really doesn’t make a lot of sense. All I hear is that the developer was not using the proper tools to create the final product.
I think this disconnect comes from a lack of training in the online community. Online learning is the way that the majority of the developers I know learned how to do their jobs. Excellent websites like the Pluralsight, Safari Books and blogs do a fantastic job of giving an overview of different languages and frameworks. And while these resources also have plenty of content about unit testing, it is often a separate topic. For brevity’s sake, the courses don’t go into things like unit testing and new developers to the technology are left watching an example of someone building a house without the right tools.
Similarly, new developers to a project are generally trained on things like code style, branching, and perhaps even something like maintaining code coverage. All the while missing the fact that writing unit tests should be an integral part of their day to day lives as software developers. It is not just an item on a checklist to prove to the code reviewer you’ve done tests. It is how you write code.
One of the major reasons developers don’t like write unit tests is that they say it’s like writing double the code. By adding unit tests after the fact, I don’t disagree with that complaint. The fact is, though, that they really were unit testing all along. Whether it’s constantly refreshing a browser, using POSTman to hit an API endpoint or deploying an app to their device to test, the concept of unit testing was there.
The problem with this type of “unit testing”, though, is that it is extremely inefficient. When I am fixing a bug, or writing a new feature, the first lines of code I write are always in a unit test file. The last thing I do is test in a browser, use POSTman or deploy to a device. Because these things are slow.
Imagine testing that an input provides the the correct results in a mobile app. Deploying an app to a device or even a simulator can take at the very least 15-30 seconds. Add to that the time it takes to manually enter the input every time, not to mention human error and you’re looking at perhaps 1 minute per test. Setting up a unit test undoubtedly takes a little bit of time, but now each test takes mere milliseconds.
Not only are there time efficiencies to gain, but now that the unit test is built you’ve got an instant regression tester. You’ve got some documentation. It’s going to be easier for developers to pick it back up later, including yourself.
I think the main cure is simply training developers of the why behind the unit tests. It’s often difficult to see a test file and a code file and understand how those came to be. Have developers who refuse to write, or who don’t believe in unit tests shadow a unit testing advocate for a couple days.
It’s likely these developers never actually watched someone code before. This is unlike almost any other profession. Doctors wouldn’t just start operating on day one. They have to watch the experienced doctors. Teachers have had 20 years of watching others teach before doing it themselves. Yet we often throw developers “into the fire” without seeing how others actually work in their day to day lives.
In addition, I think we have to do a better job of online training. In my career, I’ve learned so much from just watching senior level developers work. Not just in the area of unit testing, but in all areas. Obviously, it’s not all that efficient for developers to just sit and watch others, and that’s where online tooling can improve. Let’s get some live streams of quality developers just coding, solving real-world problems.
I think we could all learn something from watching how others do their job, and can improve our daily workflows drastically in doing so.