How to Write Unit Tests
Tackle the fear and uncertainty around unit tests by breaking them down to their building blocks.
By Akshat Shah
At GOJEK, we make sincere efforts to test our code. We have even received feedback from new joinees that the coverage they’ve witnessed at GOJEK is unparalleled. (Humblebrag quota exhausted, promise 😅).
While doing code reviews for candidates applying to GOJEK, I was surprised at learning a majority of them did not know how to write tests. This can most likely be attributed to two reasons:
Reason 1: Lack of motivation
Sometimes, people don’t believe in the ROI of unit tests. In my experience, tests have helped us:
a) refactor confidently
b) create a modular and extensible design
c) add new features speedily. Multiple blogs, and industry leaders can testify that a comprehensively tested software outlives others any time of the day.
Reason 2: Fear
Since testing is such a simple thing, people don’t ask for help fearing they’ll look stupid. During my internship, I completed all the features without a single test (for the same reason). I have seen a similar trend with mentees of mine as well.
Tests are paramount for any software that wishes to survive!
In this post, we break down what unit tests are all about, and how to write them.
So, what exactly is a unit test?🤔
Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually and independently scrutinised for proper operation.
Unit tests help verify that features behave as per the specification. They’re also referred to as specs.
For example, let’s test a feature which adds two numbers:
The above test exercises the addition feature and expects its return value (aka behaviour) to match the specifications. Exercise and expectations are the foundation blocks of all unit tests.
Unit Testing features with dependencies
Suppose our feature has external dependencies which are outside the scope of our code. We can test such features as follows:
We test the addition feature for multiple scenarios by stubbing the response from the auth server. Since all software has external dependencies, stubs (officially known as test doubles) are core blocks of unit testing. To get a deeper understanding of test doubles, I recommend reading blogs on the topic by Uncle Bob and Martin Fowler.
Setup, Teardown, Test Suites and more…
Some features require an extensive setup before they can be tested. That could consist of creating a database client, database seeding, etc. Test suites help us set up the environment pre-testing.
Exercising certain features might result in side-effects. It is considered a good practice to restore the state of the system post testing. Test suites help us in performing a teardown post-testing.
At most, unit tests consist of five steps:
teardown (aka AAA). For testing any feature, define the expectations and work backwards from there by doing setup, having necessary test doubles, exercising and finally perform a teardown.
All popular unit testing libraries have provisions for the above steps. You should be able to perform unit testing in any language by following them.
A few parting thoughts
I hope this blog convinced you about the importance of unit testing; and provided a basic understanding on how to write them. Testing is simple and the ROI is huge. Please start unit testing if you don’t do so already and let me know about your experience in the comments below.
Remember, if you’re stuck, don’t be afraid to ask!😀
At GOJEK, there is always a new challenge to be solved, and new learnings to be had. Teams develop features that make life easier for our users and other developers, and the knowledge gained is freely shared. This culture of collaboration has helped us build a Super App. Want to be part of this culture? Head to gojek.jobs, and come help us slay. 😎