Unit testing is crucial part of every good development process, but do you understand why?
I want to begin by introducing you to Matt. He’s Android developer, but unfortunately a naive one (shh, don’t tell him that!). Matt is about to be assigned to his first big task — developing an important feature for an even more important partner. He’s a bit scared, but hey! What can go wrong during simple workflow he used to read about:
A task is assigned.
A feature is developed.
The code is reviewed and accepted.
The feature is merged into main code branch.
Matt finishes coding in about 3 days and creates a pull request for his teammates to comment and see what changes were made. And so it begins…
ANGRY REVIEWER PROBLEM
Firstly, he waits for quite some time, seeing his colleagues looking at the pull request and trying to figure out what is the feature’s flow, until he receives a plethora of messages asking how exactly this code works.
OVEREAGER DEVELOPER PROBLEM
Matt patiently explains ins and outs of his implementation. However, after only a while another problem appears: “You didn’t need to add all those edge cases. It seems to me like 30% of your code is out of this task’s scope. Partner doesn’t need that much.” — says Luke, Android Team Leader.
ARCHITECTURE TRAP PROBLEM
Matt is frustrated. He tries to apply changes, but something just doesn’t fit right. The flow starts to become more cumbersome; even variable names stop to make sense and Matt suddenly feels lost in his own architecture. It takes so long to fix, but he manages, and the code is merged to the main branch!
REGRESSION FAIL PROBLEM
A month later, as Matt is about to leave the office, his younger teammate messages him saying it’s urgent: “My code is failing hard! It’s crashing the app, help me, please.” — the notification says. “Phil, how so? Wasn’t it working when you pushed it for review?” — Matt asks suspiciously. “IT WAS. I have no idea what happened. I developed it 2 months ago, and since then you were the only one changing the codebase. Help me!”. The look on Matt’s face in that moment said it all. Matt could be the one, that broke the code of his colleague by introducing new features. “How should I solve it now? I don’t even remember what my tasks were about.” — he thought.
FORGETFUL DEVELOPER PROBLEM
For weeks Matt can’t find the source of the problem he caused. He also can’t properly onboard new programmer, who his company just hired, because project’s codebase lacks any form of developer friendly documentation, that would simply explain what is the desired behavior of each code block given some input. Does this story have happy ending? Yes! Matt discovers unit testing!
TACKLING ANGRY REVIEWER PROBLEM
It’s easy to get lost and angry in the world of pull requests and code review. Out of many lines of code, which are added, deleted or modified during development process, unit tests stand out and provide a nice and safe place to start understanding the desired flow.
TACKLING OVEREAGER DEVELOPER PROBLEM
As developers, we spend a lot of time wondering about how to implement a feature but tend to forget what it should contain. An early definition of that using tests (test-driven development) helps to change perspective and maintain focus on the end goal of the task.
TACKLING ARCHITECTURE TRAP PROBLEM
I believe that many developers lack one crucial thing when implementing yet another architecture: a deep understanding of it. Whether it’s MVP, MVVM or recently popular MVI you need to see what’s inside, dive deep and tear it apart. Otherwise, there’s a high risk of missing key contract principle and, in the end, producing a framework, which impedes future development. Unit testing allows to catch those misconceptions and misunderstandings at an early stage.
TACKLING REGRESSION FAIL PROBLEM
The more complex a codebase, the more time it takes to perform manual testing. Luckily, unit tests are very easy to automate, with the help of CI tool like Bitrise, and given a good coverage, they can save developers a lot of time by detecting breaking changes, that new implementation introduced.
TACKLING FORGETFUL DEVELOPER PROBLEM
You can think of unit tests as a developer-friendly documentation, which helps to recall all necessary implementation details in no time, even after a few months break.
Ever since I started extensively testing my code, I feel more confident in it. I developed a new level of architecture understanding and new, more effective, approach to code review. During early days of my career I was told, that testing is a waste of time, since you manually check if your app has errors anyway, but please note, that creating products with fewer bugs, in spite of owing it to unit tests too, did not appear during argumentation in this article. To me, listing bug-free code as the only merit of automated testing is like naming purchase of a new pair of sneakers as the sole advantage of winning 1 million dollars. With that being said, I want to wish you all happy testing!