Is Unit Testing Really That Important?

Is Unit Testing Really That Important?

Short answer: Yes.

Long answer: Yes, Unit Testing is that important.

52uxzb.jpg

If you just searched the web for unit testing, congratulations! You're on the right track. The sooner you start including tests in your code the better.

I wish I knew this when I started my career as an Android developer. I remember being taught about using design patterns such as MVP for decoupling the business logic from the view business and thus, among other things, have testable code. However, we didn't implement tests therefore I never really internalise the benefits of using design patterns nor unit testing. It seemed to me that it only made the project more difficult to understand and follow, code more verbose and I ended up coding in that way because "it was how it was supposed to be done".

It took me years to understand the importance of design patterns and unit testing (that's why it's important to start with unit testing soon) but once you do it, you'll never look back and this is great news.

There are several benefits, technical and non-technical, about unit testing that I've found out over the years.

Technical benefits

Improve our code

We always write clean code, right? RIGHT!? Well, no...not always at least. Unit testing helps us to spot complex logic (e.g. a method that does many things or a bunch of required setup in the test file is a strong indicator that the class under test could be doing many things as well) because complex logic is not easy to test, therefore we may want to refactor it and make it easier to test.

More than once I've had the following thought "Wait...I think I've tested this same behaviour before...". And effectively I find that I already have that same (or similar) logic implemented in the codebase so it's a strong candidate for being extracted as a helper or util and being reused, thus avoid code duplication.

Make our code more reliable

For a Java developer, a crash of the application due to an NPE is as frequent as a lockdown nowadays. The reason is that when you're coding, it's not rare that you take for granted that most of the variables have a value assigned. This is not always the case and testing highlights it before our eyes. You are not going to fix something if you don't even know it's broken. I've named NPE but it applies to more things such as missing to consider conditional branches (if-else).

Spot edge cases

When we code, we think about all the possibilities and/or scenarios that our app may face and we cover them. Or at least we think so. It's very common that when we're testing a piece of code, we find ourselves having the following conversation:

"Okay, so this method receives a list as an argument and it can't be null because I've annotated it as @NonNull therefore I don't have to test the scenario in which the list is null, yeah!!! Hold on, what if the list is empty?"

At this point, new questions arise:

  • Should I treat an empty list as an error?
  • Should I add a default value/object to the list when it is empty?
  • Should I handle the empty list in this method or should the caller to the method handle it and ensure that the list is not empty?

Something as simple as an empty list is a source of questions and unit testing begins to show its power.

Encourage refactoring

Our tests work as a safety net for our production code so, if we have a good test suite, we'll be more willing to refactor if we know unconsciously that we won't break anything without being warned.

Non-technical benefits

Stand out

If you're a less experienced developer in job hunting, knowing about unit testing (even if you're not that great at it yet) can make you stand out among other candidates.

And if you're a more experienced developer and you don't know about testing, you will stand out as well. Not in the way that you want to though.

Detect red flags

If during an interview, you're not asked about unit testing or when you ask about it (you should always ask questions in an interview by the way), the interviewer gives you a vague answer (no mention about code coverage, tools for code quality such as SonarQube, frameworks for testing such as Mockito and Robolectric) for Android, then you know that you have to be in alert to spot more red flags "Do they have code review? What about their CI/CD?" If you spot a lot of red flags, you might want to consider if that is a place where you want to work.

Downsides

Time-consuming

Frequently, you spend more time testing the production code you just wrote than writing the code itself. Especially when you're not used to testing or, even worse, when you have to test legacy code that was never tested, therefore likely not very testable.

Clashes with teammates

If you work in a company in which the culture of testing is little or your teammates barely test their code because they think that testing is not important or a waste of time, most likely there will be frictions. You may need to make the extra effort and educate them.

Conclusion

In my experience, you should add unit testing to your skill set because the benefits outweigh the downsides and there is no turning back. It makes you a better developer because it obliges you to architecture your app, to think about why you're doing things in some way and not in another, to understand why concepts such as single responsibility or decoupling are important and the like.