When it comes to unit testing, there is always two sides for the coin. Does unit testing pay off? Is it worth it?

Image for post

Source: https://github.com/egonelbre/gophers

Be humble about what your unit tests can achieve, unless you have an extrinsic requirements oracle for the unit under test. Unit tests are unlikely to test more than one trillionth of the functionality of any given method in a reasonable testing cycle.

— James O Coplien on “Why Most Unit Testing is a Waste”

Image for post

Photo by Lacie Slezak on Unsplash. Unit Testing might make you feel stressed like this woman. She throws all the TDD books because TDD can be tiring sometimes.

This article touches up on my thoughts on unit testing. If you’re looking for a hands-on, I will soon have a Go language tutorial on “Gorm for SQL in Go”. If you are new to unit testing, I suggest you read up some of these then try two different exercises:

  • Try building a dead simple project and add unit tests whenever testable. e.g. Building a Parking Lot system. Here is one simple problem, overkilled solution + unit test in my github. No third-party library allowed here.
  • Try building applications. For example, build a web application using a minimalist web framework + ORM / database connector library. Now remember, unit test is all about isolated test but your code now depends on other components. How do you add a unit test? And what benefits does it give you here?

Table of Content

**I. Unit Testing — **What is and what is NOT Unit Testing?

II. Advantage of Unit Testing — How valuable is a well-writen Unit Tests?

**III. Misbelief on Advantage of Unit Testing — **What it won’t give you, ever.

IV. The Cost of Unit Testing — Cost of unit testing and Risk for writing a bad one.

**V. When is Unit Testing Valuable then? — **Should you then do other kind of testing?

What this article about?

I’m going to talk a bit about unit testing because I think it’s worth to pause and think:

  • Does Unit Testing a must? I have seen many cases where it is not worth doing and its much worth to skip towards functional tests instead. Its not a norm either, despite many books and resources encourage unit testing and even TDD. As a software engineer, you must not blindly follow what the book, tutors, or what your tech lead says.
  • But it’s just unit testing, right? Isn’t it easy and quick? The answer is a big NO but of course it depends. For most of my backend application, it is a big NO and it is tedious to write a well written unit test. I’m talking just the unit tests, not functional or integration tests yet.

What this is not about?

  • This is NOT an anti unit testing neither I’m suggesting you to delete you testing code.
  • This is NOT a tutorial on how to write a test.

Unit Testing

I think sooner or later we will have to talk about unit testing and why it is very difficult. Unit testing is not as easy as I thought would be back then. It requires one module to be isolated from its external dependencies such as database layer or API client.

Many developers that I spoke to misunderstand what is and what is NOT a unit test. For some of those, unit test is described as “just testing a single function” which is far from truth and it not easy once you created a fairly complex application.

Image for post

Photo by Jon Flobrant on Unsplash. When unit testing stressed you out, meditating in bikini helps to ease your burden in mind. But do you know what else helps?

There are many formal definitions and articles greatly explaining what is Integration Test vs Unit Test. Here is a recap in my own language:

  • Integration Test: test more than one component and how they function together. For instance, how another system interacts with your system or the database interacts with your data abstraction layer. Usually this requires a fully installed system, although in its purest forms it does not.
  • Unit Test: is a level of software testing where individual units/ components of a software are tested. The purpose is to validate that each unit of the software performs as designed. A unit is the smallest part of any software. It usually has one or a few inputs and usually a single output which we call a function or method.

In a nutshell, unit testing requires three key points:

  • White Box testing. This means the code is executed as expected for known inputs and edge cases. For example, if you are testing your applications’ data layer, you need to test for SQL or Query that is generated by your ORM. Then see if the query is exactly like what you wanted when you use the ORM library.
  • Extreme Modularity and Code splitting. This one goes hand by hand with doing White box testing. Unit testing is about testing the smallest unit possible in any software. A modular code improves testability when you can build bottom up from the smallest and reusable units possible up to more complex function. However, code splitting could possibly destroy your software architecture you have designed earlier.
  • Isolation and Mock. Any dependency on other components, external or internal should be mocked. That is the hardline of TDD developer. Mocking in my view is the most difficult part. Your code must be well structured and adhere to SOLID principle. The scope of your classes and modules must be well defined so that when they are tested, you can mock the dependencies and vice versa.

Advantage of Well-Implemented Unit Testing

Hard work must pay off doesn’t it? Well, it depends but what I know for sure, testing is less but arguably quite a brain puzzle and more of hard work. Then what do you get from doing these unit testing?

In my view, there are two major advantages that a unit testing provides in long future. How long is long? Depends on your sprints but for me, starting from 2nd sprints cycle onward, I have already felt the benefit as follows:

  1. Automation for Catching Bugs. I don’t think this is a surprise and need explaination. Team collaboration in code sprints means lot of code being pushed, lots of changes, and hence requires automated testing before merging new features, bug fixing, refactoring, configs changes, etc.
  2. Explainable, Interpretable Error Debugging. This is the part that I think most valuable. For me, the cost of doing unit test only worth if it saves me from days of debugging. Well written code can immediately pinpoint the exact reason for a bug to occur, in which specific function/method in which module. This feature, however, requires you to design your unit tests and develop the testing code well, including the result logging and test labelling.
  3. Unofficial Guide or Docs. Good tests can also serve as an unofficial guide to using the interface. This benefit actually applies to any kind of testing. The tests that are well written demonstrate how to use your API and what are the expected outcome in clear manner.

#software-testing #programming-paradigms #code #unit-testing #software-engineering

Rethinking Unit Testing in Software Development
1.55 GEEK