Why should we write unit tests? I guess most developers have thought about this already at some stage in their career, and there are a lot of pros and cons of course. In this article, I’ll show you my #1 reason why I’m using unit testing, by pointing out how software development works without unit testing, and how it changes once you adapt a reasonable practice of testing your code.
So, how does your world as a developer look like without unit testing? You work on a feature, and once your code compiles, you click around in the UI a bit and see if everything looks and behaves as you expect. If you find a bug, you note it somewhere, and hope that someone else fixes it – because fixing a bug will take a lot of time. Because in the end, you have nowhere to start searching for the bug. I mean you know what you clicked. But still, there are several layers of code that could have caused the issue – not talking about side effects yet! So, better let someone else fix the problem. But what if you now have to ship your software? Are you convinced that everything works as expected? Even if you have fixed all the found errors, are you sure that there is no severe bug left? Or your last-minute commit will cause some login issues? Usually, this results in an extensive manual testing session before a release, to ease your mind. Also, this often leads to a lot of bugs that you still find, but don’t have the time to fix. So you prioritize those who might do the most harm. But in the end, you know that your software still has some errors. But if there are no major ones left, usually, you still ship. But did you maybe miss some major ones? What do your users say to the bugs they find? What is your team lead gonne say, once users start complaining? In the end, only time will show. But until then, you will have to life with the fear of uncertainty. And before the next release, everything will start over again.
Once you adapt a practice of creating unit tests to a degree that you know what’s going on in your software, but are still able to keep them up to date, this world changes drastically. At each point in time, you have this level of certainty about what parts of your software are currently working and what parts are not working. So if someone asks you whether you’re ready to ship, you always know what to answer (and most of the time, it is yes). You can even define a minimum standard (set of test cases that have to pass) required to allow shipment. With this standard, you can ship any time. And in practice, this is what many “agile companies” such as Tesla or Amazon also do. They ship new software several times a day (e.g. one deployment every few seconds in the case of Amazon), because they are always certain about the state of quality – so they can ship without the fear of thousands of complaints (or even car crashes in the case of Tesla).So what’s your takeaway message from this article? Once you start unit testing, and also keep your tests up to date, you can ship your software without fear, at any time. Let me know your take on this in the comments section below!
Whereas software testers are the professionals explaining everyone why it is most crucial to exhaustively test every part of your software, it is often difficult for developers to see the benefit of testing. However, especially when it comes to unit testing, the developer is the one that has to do most of the work – but also receives 10x benefits compared to the effort spent on writing test code. Here are three use cases how unit testing will benefit your work as a software developer.
1. Fix before push: Did you ever check in your code, and afterwards notice that your push crushed the whole code base (or your not-so-nice co-worker maybe made you notice)? If you didn’t, you can simply ignore this use case. If you did, it might make sense to consider unit testing. Running tests that cover different parts of the software automatically gives you feedback on which parts you crashed with your changes. By running your unit tests before every check-in, and making sure that all of them pass, you can make sure that the pushed software also works as expected. With a continuous integration build, you can even enforce this, by automatically running unit tests on the pushed code before adding it to the code base.
2. Test-Driven Development: One of the worst feelings when writing code is to identify that you have to throw away a part of your software, after working several hours, days, or even weeks on it. This is why you want to develop the correct code in the first place (I’ve called this think-specify-code before: Try This For a Week And Speed Up Your Coding Productivity 10x). Unit tests can be the perfect tool to do so. Writing test code is less effort than writing software, and as a developer, you are usually way less attached to your tests than to the actual software code you have written. Thus, throwing away unit tests is way easier than throwing away a part of your software. So why not try out whether your ideas work out in code by writing unit tests that validate this imiaginary code? How can I write unit tests for imaginary code you ask? Well this practice is around quite some time already, and called Test-Driven Development – read up if you are interested!
3. Documentation: Let’s think about this amazing feeling when you ship software. The code that you have been working on is finally released into the wild. Nothing crashed, everything worked, and noone found the nasty workarounds you have built last-minute to get everything running before the deadline. But what happens, if after some months, you have to work on this software again? Maybe on the next release, maybe on some change request that your customer or the software users requested? Do you know where to take off? Which parts of the code have to be touched in order to add new functionality? Which parts you better not touch, because they might break the whole system? If you don’t know, you might be lacking the necessary documentation. Missing (or even worse: outdated) documentation is one on the main time killers of developers, and the top reason why software is thrown away and rebuilt. However, there is a reason why in most of your projects, documentation is missing or outdated. Writing documentation is hard. What is even harder than writing documentation is maintaining it. Every change in the code requires even more time if you have to document it, and think about which implications it might have to other parts of your documentation in order to maintain consistency. So why not reuse unit tests to provide documentation? Reading unit tests gives you a good impression of the structure of your software, and the functionality of individual software parts (assuming that you stick to the correct naming pattern, which you can verify using this checklist: A Checklist for Assessing the Quality of your Unit Tests). Running unit tests (and checking how many of them fail) before changing the software gives you a first impression of the quickfixes that have been made briefly before deployment. Running unit tests after some changes gives you a good overview on which parts of the software you have crashed with your changes. So keep your unit tests up to date, use them wisely, and you have a pretty good documentation already!
What is your experience with these use cases? Which use cases would you like to add to this list? Let me know in the comments section below!
When you visit any web site, it may store or retrieve information on your browser, mostly in the form of cookies. Control your personal Cookie Services here.