The real joy of writing unit tests

Duncan Grant
5 min readJan 13, 2020

--

At this point, articles evangelising test driven development have been done to death. However, I think they often miss the big selling point to people who have tried or been forced to write tests and never enjoyed the task. Programmers who work alone, or small teams working on smaller projects will often never seen the point of introducing tests which appear to be more of a hindrance than a help. Too often TDD articles lead with the virtue of how tests are good for teams or good for maintaining code bases before they become legacy, but I’m going to tell my story of test driven development and explain the understated reason that unit tests could be useful to you personally in your next project, no matter how small that project may be.

I think some of the most fascinating lessons to learn are the ones which have been right under your nose the whole time, but never truly grasped, until one day everything clicks and you are in awe that it has taken so long to discover something that makes so much sense. For me, such a lesson came when I needed help and test driven development showed me the path.

2010 was the year I first ‘got’ JavaScript, when I built a bookmarklet to parse, read, explore and edit RDFa from webpages. Reading online books such as Addy Osmani’s essential js design patterns, really opened my mind to the power of JavaScript. Before the age of let and const, arrow functions and classes and even before promises, when we were still wrangling with callback hell, I found that JavaScript was flexible enough to write it in a way that suits you, whether it be object-oriented, functional or simple imperative scripts. JavaScript has received a lot of criticism from people who wish it could be more like one programming language or another, but the truth is, for many programmers like me, we are completely satisfied with JavaScript. Not having to fiddle around with types and generics and rewriting interfaces when something changes is very freeing, letting us get from thought to code without any annoying barriers in the way — the code flows freely. It is for this reason that I love JavaScript.

For these reasons and more, I never really liked writing tests. I understand the relevance of unit testing, to define behaviour and ensure that your code will always satisfy this behaviour. So in the case that you are going to do some refactoring or add new features, you can be sure that you are not breaking existing functionality or introducing new bugs in the process. That makes perfect sense and is a valid reason to write unit tests, however it doesn’t make it any less of a chore. If testing is a chore and it feels like it just slows down the process of me writing code then I don’t like it and will only endeavour to write tests for big projects when I have to.

Let me tell you why people actually love test driven development, and it’s not for the reason I mentioned above. The reason test driven development is great is because it eases cognitive load.

Last December, I thought I’d freshen up my python skills, so I decided to follow along the advent of code. The advent of code is essentially a set of programming puzzles given to you in the form of an advent calendar (a new puzzle every day from 1st to 24th of December). You can use whatever programming language you like, but the key thing is that the puzzles are sufficiently complex to make even the most seasoned programmer have to think for a moment before solving them. I started by writing code to solve the puzzles and just doing a simple print() call with my answer. But when the puzzles got more complex and my code had been separated in multiple functions and classes, I found that trying to debug where I went wrong was taking significant time. Moreover, advent of code typically gives you a handful of sample inputs with their corresponding expected outputs which you can use directly in test cases. Writing unit tests allowed me to hone in on bugs much faster, but more importantly it allowed me to not have to think. Instead of having to juggle multiple thoughts in my brain at once: e.g. “this function must take X input and return Y output, it needs to call function Z which needs to transform the data in such a way, I need to loop over the data to get this value then transform it, then loop over the inner values of that array before building up a new data structure on which I will get the nth item to be my answer”. This is the usual thinking that goes into writing code to solve a complex problem without using test driven development and it is tricky because you are holding so many moving parts in your brain at once, that once you try to write your next line of code, you only have so much brain power left to complete it.

The answer is to write unit tests. When complexity is sufficient, write several unit tests around the problem area to test each function involved. This way you can just tinker and write code until each test, one at a time, is succeeding. No more juggling multiple thoughts in your brain, you don’t have to think about the bigger picture of your system as well as the minute details all at once. It’s more relaxing to just solve the most granular part of the problem to satisfy a test and move on. I found that with the advent of code, when I was struggling with a particular problem, I could switch to test driven development mode and solve it much more easily and quickly.

I’ve now started a new JavaScript project and am using Jest to write tests as I go and as necessary, and it is working nicely. I have written tests in the past but now my attitude, understanding and appreciation of them is that much better.

Now I can see unit tests as one more tool in the box. There will come a time as a project matures that unit tests to secure behaviour are a necessary burden, when your code is being reused across teams and projects (and it’s true that it is much easier to write tests as you go rather than as a later refactor). That is not where the joy of unit tests lies though.

The real joy and power of unit tests is in freeing up all of your brain’s energy to solve the problem at hand. It brings me back to one of the things I love most about JavaScript, bringing thought to code quickly and with as little effort as possible.

--

--