Unit Tests: Ain’t nobody got time for that!
Author: Nasif Ahmed
Technical Lead and Software Architect
Software Architecture / Java / Big Data / Cognitive Systems / Data Science
- Are you sure fixing this bug won’t cause a few more bugs to appear?
- By making this little change, are you sure it won’t break any existing logic?
- Is your codebase adhering to sound design principles? Is it maintainable?
- How many times did you write a debug log just to check if your software is working during development?
- We’re doing a deployment tonight. Is everything working alright?
- Is your system CI/CD able?
There are no definite answers to these questions, right? We all have some methods or classes in mind which we may get wrong while answering these questions. It’s difficult if not impossible to be 100% confident about a codebase, but the level of confidence can be increased drastically. But how?

This discussion is all about gaining more confidence about your codebase by writing unit tests. I won’t go into any technical details though; I’ll mainly try to answer these two questions:
- What is a Unit Test?
- Why should we write them?
So, what is a unit test?
“.. a unit test is a piece of code that invokes another piece of code and checks the correctness of some assumptions afterward ..“
In a nutshell, it’s like a second compiler. It doesn’t matter if we have thousands of lines of code that compiles, builds, and deploys. From the end user’s perspective, the only thing that matters is whether our code works according to their intentions. To meet this intention, unit tests play a crucial role.
Why should we care?
I guess we already got an idea of why we should care, but let’s dig a little deeper.
- Making changes and refactoring is not a problem anymore
- Enforces good design and better practices
- Makes deployment a piece of cake
Making changes is not a problem anymore
Whenever we think of making a new change to an existing codebase, or adding a new feature, or even just fixing a bug, we need to take a lot of things into consideration. Is it going to break something which currently works? Is it going to introduce a new bug? Will the next developer who’ll work with the code easily understand what the code does? When the codebase is buttressed with a set of unit tests, these are no longer causes for headaches. For every little ‘breaking’ change, the corresponding unit test will fail. Fixing that test will make sure the new change does not break anything. The same goes for bug fixing and refactoring.
Enforces good design principles
Separation of concerns, loose coupling and high cohesion, inversion of control, dependency injection, open-closed principles and what not! Sound familiar? To write unit tests properly, one must write testable code. And when writing testable code, all the sound practices of maintainable code comes into play. Writing unit tests forces a codebase to be loosely coupled so that a unit of work can be tested individually. Maintaining huge dependencies is not going to make a developer lose any sleep. Proper separation of concern is maintained automatically by writing testable code.

Makes deployment a piece of cake
When there is a set of automated tests, deployment becomes way too easy! All we need to do is press a button, and voila! The primary prerequisite of a one-touch deploy is to have proper unit tests. Tools like Jenkins, Bamboo, Travis etc. provide virtually everything required to have a painless deployment system. However, before pushing new changes to production, having well-written unit tests is a must.
That’s about it. Every modern programming language has its own testing framework. Here are a few examples:
- Java: JUnit, TestNG, Mockito, PowerMock
- C#: NUnit, Moq
- Javascript: Karma, Jasmine, Mocha, Should
- PHP: PHPUnit
- Python: unittest, pytest
