Unit testing allows a developer to create validation logic at the lowest level of their software solution. These tests, forming the base of the test pyramid, create a stable foundation upon which robust software solutions can be built and evolved. Technical Manager, Tarun Khandelwal, takes us through his journey as a software developer, exploring pitfalls he has encountered, and how he has overcome these with the teams he has led.
In working with many teams and engineers in India, the United States, and Europe, I have found the following to be the most common questions asked by engineers about unit testing:
“I don’t know if it will help.”
“Is it really required?”
“How many should we write?”
Other concerns include how to best utilize a unit test and how to avoid impact on the development of the product.
I became fascinated with writing unit tests when I joined the software industry nine years ago.
I joined In Time Tec in 2011, with a team of 40 engineers. At the time, everyone was talking about unit testing but there were no situations that called for it. With the growth of clients, projects, and complexity, unit tests quickly became one of the key aspects of development at In Time Tec.
As I have become more familiar with unit testing, I have learned a few common reasons teams often skip writing them:
Having clarity around these concerns enables engineers to write quality and clean unit tests.
Why write unit tests?
When I learned about unit testing, I saw it as a good automated mechanism to validate the code instead of spending time with all permutations and combinations manually. Applying the concept of adding in tests as I developed code, I merely went about adding in unit tests for several services classes on the project I was working on. A week later, I had to make some changes to the functionality in these services classes, and I found myself having to also update the associated tests as well. This experience helped me to see that just writing unit tests does not bring quality, but rather the combination of coding best practices and principles which include unit testing together helps us write better code.
Over time, I found many other benefits of having unit tests:
Unit tests as a part of development
With most newer engineers, unit tests take a back seat because they are not taught as a part of software development; something that still needs to be added to software engineering curriculum a lot of universities. However, if unit tests are not a part of the development from the beginning, the backlog grows and it becomes difficult to bring them in without impacting feature development or bringing additional engineers to the team, both of which are additional costs to stakeholders.
I experienced this set back a couple of years ago when I joined a project with an existing team that had not written any unit tests. Since the team had never estimated unit tests as a part of their work, when we implemented them it caused the project velocity to slow and we ultimately discarded the tests in favor of delivering on time with quality. We worked to get the project management and stakeholders were aligned with our new development strategy that included the unit tests and it became a normal part of the process.
Unit test setup is tedious but necessary
If you have spent time writing unit test cases, you know what I am talking about. In a recent project, I found 100+ lines of code written just for the setup. After spending some time on it, I was able to convert them into 10 lines of code. Now that required some time from my end, but in the end, I could see happy faces of developers who are writing unit tests for that project.
Unit testing requires the same amount of effort as development, at least in the initial phase of bringing them into existence. There are many blogs that discuss standard ways of implementation and how to use different unit test frameworks and libraries but a good amount of research is often required before finding the best blog or article addressing the specific need.
So, as a developer/technical lead, include unit testing in your research when looking for different development platforms and framework and keep in mind about the effort it may take to have a functional setup in place.
Writing unit test CAN take more time than feature development
It’s easy to make unit tests complex without proper setup and guidelines in places. I have been in situations where I spent half a day writing implementation for a feature and it took me a couple of days to finish unit test for the same feature. This time investment is because writing a unit test is not just a one-step process; it includes these three steps: Arrange, Act, and Assert.
The last two steps, Act and Assert, don’t usually take very long. It’s the first step, Arrange, where most of the time is spent. To help improve your productivity creating unit tests, focus on the Arrange step and take the time to get the prerequisites in your project, ensuring you can successfully build and run your tests, and address any issues with previously existing tests that may occur. Then you can focus on the proper arrangement for your new tests and develop those in a timely manner.
By following programming principles to keep classes simple, making sure not to mix multiple aspects of programming, and using the unit test framework the way it is supposed to be used can all cut down on this time.
All of the initial concerns are real and it will always require effort and attention to do anything properly. Ultimately, there are a few tips for easily bringing unit test into your project:
Unit testing can really save time and effort on your software development projects in the long run. If you are not running unit tests, now is the time to really dig into and take seriously the benefits of starting.