DEV Community

alexrai
alexrai

Posted on

Why I Stopped Treating Testing Like a Phase and Started Treating It Like a Risk Budget

Most of the testing advice I absorbed early in my career was secretly about scheduling. Test after you build. Automate the regression suite. Shift left. All useful, all real, and all quietly dodging the only question that actually determines whether testing pays off: what deserves to be tested in the first place, and how much.

It took me an embarrassingly long time to realize that testing is not a phase you pass through. It is a budget you allocate. And the frameworks that survived contact with real projects were the ones that treated it that way.

The idea I borrowed from a 1980s process model

The mental shift came from an unlikely place. I was reading about the spiral model in software engineering, a process model Barry Boehm published in 1986, mostly out of historical curiosity. I expected a dusty relic. What I found was the cleanest articulation of an idea I had been fumbling toward for years.

The spiral model organizes a project as repeating loops, and every loop starts by asking one question before anything gets built: what is the scariest unknown right now, and how do we attack it cheaply? Risk is not a checkbox at kickoff. It is the engine that decides what happens next. You confront the thing most likely to sink the project first, usually with a throwaway prototype, and you only spend real money once the uncertainty is paid down.

Swap "project" for "test suite" and the whole thing clicks. Your riskiest unknowns are exactly where your testing effort belongs, and everything else is a rounding error you can afford to under-cover.

Coverage is a terrible target

Here is the trap almost every team falls into, mine included. Someone puts a coverage percentage on a dashboard, and from that moment the team optimizes for the number instead of for safety. You end up with beautiful coverage of the easy paths, the simple getters, the well-documented endpoints, and a gaping hole exactly where the danger lives: the concurrency edge, the third-party timeout, the permission boundary, the money-moving transaction.

The suite looks healthy. The risk barely moved. The dashboard has become a confidence machine that manufactures the wrong feeling.

A coverage number cannot tell you that the payment endpoint matters more than the avatar upload. Only a human who understands the consequences can rank those, and that ranking is the single most valuable artifact your testing effort produces.

What actually changed in how I work

The practical version of this turned out to be less about tools and more about sequence. Good software testing strategies are fundamentally allocation documents. They spend finite hours and finite pipeline minutes deliberately, and the most important lines in them are not what to test but what the team consciously chooses not to.

These days, before writing a single test on a new feature, I try to answer four questions in plain language:

  1. What breaks a user's day if it fails here? That gets the deepest coverage.
  2. What has broken before? Every past incident earns a permanent regression test, no exceptions.
  3. What is genuinely hard to get right? Concurrency, money, permissions, external dependencies. Depth goes here.
  4. What can I honestly afford to under-test? Naming this out loud is what frees up the budget for the first three.

Only after that do I care which framework or tool executes the plan. The tooling is a multiplier. The strategy is the aim. Point a fast tool at no strategy and you generate volume exactly where it is easiest to generate, which is almost never where the risk is.

The uncomfortable part

The hard truth buried in all of this is that a good testing strategy requires you to accept some risk on purpose. That feels wrong. Every instinct says test everything. But testing everything with equal depth is just testing nothing with priority, and finite teams do not have the luxury of pretending their attention is infinite.

The spiral model's oldest lesson is that maturity is not the absence of risk, it is the deliberate management of it. Confront the biggest unknown first. Buy information cheaply before spending heavily. Decide, out loud and on purpose, what you are not going to chase.

I am not running formal spiral loops on my projects, and you probably will not either. But treating testing as a risk budget rather than a phase to complete has done more for the actual reliability of the things I ship than any amount of coverage-chasing ever did. The framework is forty years old. The mistake it fixes is being made in a hundred repos right now.

What is the one thing your team consciously decided not to test, and did it come back to bite you? I collect these stories.

Top comments (0)