Mistake #2: Starting with Unit Tests
Starting the shift-left initative by developers writing unit tests (and aiming for 80% code coverage). But no bug reduction! And developers wasting time!
📢 My next Live Q&A Session about Unit Tests is on Wed 30th April 17:00. If you’re an Optivem Journal paid member, get your 100% discount ticket.
Upgrade to join the Live Q&A for free:
Many companies come to a realization that you can’t just add quality on top, you can’t just have QA Engineers as a gatekeeper to quality (with their E2E Tests). Instead, you need to build in quality during the work of Developers. This is where companies jump from one extreme to another extreme, they focus all their effort now on Developer & Unit Tests. So the developers achieve the 80% code coverage, or 90% code coverage or even 100% code coverage… but NOT reduction regression bugs AND they complain about writing Unit Tests. So then, Management abandons the initiative.
If you start with Unit Tests….
… you will NOT reduce user-facing bugs.
… you will NOT make a business impact.
In a Legacy Project with no tests, we could start with any test type. Indeed, many companies start with Unit Tests. If you read materials by Uncle Bob and others, where Unit Test is such a huge focus, indeed you might be pushed to start with Unit Tests. Many Engineering Managers do push starting with Unit Tests too, esp. since then they can easily use Code Coverage targets to track whether enough Unit Tests were written.
However, there’s a problem of starting with Unit Tests, it’s low-ROI & high risk. It is low-ROI because it offers isolated protection against regression bugs - only for localized application-side business-logic regression bug protection. Here are the risks of starting with Unit Tests, they have limited regression bug protection:
Unit Tests do NOT protect us against regression bugs in database & file access
Unit Tests do NOT protect us against regression bugs in microservice communication
Unit Tests do NOT protect us against regression bugs in communication with external systems
On the other hand, there can be a significant cost in introducing Unit Tests when the business logic code is highly coupled with presentation logic code and infrastructure logic, so then we need to redesign the source code to ensure it’s unit testable. In this process, it might be possible that the unit test passes but that we introduced a user-facing regression bug.
You should start with Acceptance Tests instead.
Acceptance tests are high-ROI & low risk. Acceptance Tests offer value in that they protect us against user-facing regression bugs (together with External System Contract Tests). They are relatively low-cost to write and low-risk because they don’t require system redesign.
That’s exactly why we start with Acceptance Tests (and not Unit Tests) within TDD in Legacy Code, because it’s the safest way AND it yields the greatest ROI of automated testing efforts.
📢 My next Live Q&A Session about Unit Tests is on Wed 30th April 17:00.
Starting with Acceptance Tests seems like the most practical approach, especially in legacy systems. 🙌
Great article! I think one big issue is properly defining what a unit is for a given software solution, in legacy code the first goal is to tame the beast and acceptance test can help setting things in place. But proper unit testing should be the way to write new code in my opinion.