Skip to content
Amine Mekki
Back to articles

Tests that buy confidence, not coverage

Coverage percentages measure execution, not confidence. A useful test suite is designed around a different question: what would let me refactor without fear?

  • Testing
  • Clean code
  • TypeScript

Every team says they value testing. Fewer can answer the question that actually matters: which failures would this suite catch? A suite can execute 90% of lines and catch almost nothing: assert that mocks were called, snapshot markup nobody reads, verify that the framework works. The metric goes up; the confidence does not.

Test behavior at the boundary

The tests I keep are the ones that exercise a meaningful surface: given this input at the module boundary, this observable behavior comes out. Business rules through their public function. An API endpoint through a request. A slug generator through its strings. These tests survive refactors because they pin down what the system does, not how it currently happens to do it.

Tests coupled to internals do the opposite: every refactor breaks them, so refactors stop happening, which is exactly backwards. The suite exists to make change safe, and instead it taxes change.

Let the type system take its share

In strict TypeScript, whole categories of tests are redundant: nullability, wrong shapes, missing fields at boundaries validated by a schema. Let the compiler and the schema hold that line, and spend test effort where types cannot reach: logic, edge cases, integration between real parts.

The refactor test

My acceptance criterion for a suite is simple: could I restructure the internals of a module and trust a green run? If yes, the tests are an asset. If a refactor means rewriting the tests too, they were never testing behavior. They were a second copy of the implementation, and every copy is a liability.