Most Developers

Don’t Know How to Test

Every developer knows we should write unit tests in order to prevent defects from being deployed to production.

What most developers don’t know are the essential ingredients of every unit test. I can’t begin to count the number of times I’ve seen a unit test fail, only to investigate and discover that I have absolutely no idea what feature the developer was trying to test, let alone how it went wrong or why it matters.

In a recent project of mine, we let a gigantic swath of unit tests enter the test suite with absolutely no description whatsoever of the test’s purpose. We have a great team, so I let my guard down. The result? We still have a ton of unit tests that only the author can really make sense of.

Luckily, we’re completely redesigning the API, and we’re going to throw the entire suite away and start from scratch — otherwise, this would be priority #1 on my fix list.

Don’t let this happen to you.

Why Bother with Test Discipline?

Your tests are your first and best line of defense against software defects. Your tests are more important than linting & static analysis (which can only find a subclass of errors, not problems with your actual program logic). Tests are as important as the implementation itself (all that matters is that the code meets the requirement — how it’s implemented doesn’t matter at all unless it’s implemented poorly).

Unit tests combine many features that make them your secret weapon to application success:

Design aid: Writing tests first gives you a clearer perspective on the ideal API design. Feature documentation (for developers): Test descriptions enshrine in code every implemented feature requirement. Test your developer understanding: Does the developer understand the problem enough to articulate in code all critical component requirements? Quality Assurance: Manual QA is error prone. In my experience, it’s impossible for a developer to remember all features that need testing after making a change to refactor, add new features, or remove features. Continuous Delivery Aid: Automated QA affords the opportunity to automatically prevent broken builds from being deployed to production.

Unit tests don’t need to be twisted or manipulated to serve all of those broad-ranging goals. Rather, it is in the essential nature of a unit test to satisfy all of those needs. These benefits are all side-effects of a well-written test suite with good coverage.

The Science of TDD

The evidence says:

TDD can reduce bug density.

TDD can encourage more modular designs (enhancing software agility/team velocity).

(enhancing software agility/team velocity). TDD can reduce code complexity.

Says science: There is significant empirical evidence that TDD works*.

Write Tests First

Studies from Microsoft Research, IBM, and Springer tested the efficacy of test-first vs test-after methodologies and consistently found that a test-first process produces better results than adding tests later. It is resoundingly clear: Before you implement, write the test.