Regression strategy without paralysis
Full regression every sprint is a fantasy. Here is how I choose what to re-check so releases stay honest without freezing delivery.
Regression panic usually arrives two days before a release. Someone asks whether “full regression” was run, nobody can say what full means, and the team either reruns several hundred cases against the clock or quietly skips most of them and hopes. Both come from the same gap: nobody agreed what must stay true from release to release.
Full regression testing every sprint is a fantasy on any product of real size. I have worked in two-week sprints and monthly releases, on teams of five and programmes of more than forty, and the pack always grows faster than the time to run it. What works is a strategy that makes the choice explicit: what gets re-checked is decided, and what does not is written down.
What regression testing has to protect
Start with the journeys that earn revenue, meet a compliance obligation or hold user trust. Those are the immovable core. On a parking platform that might be starting a session, paying for it and being able to prove you paid. On a facilities platform, raising a request and seeing it reach the person who has to act on it.
The core is short on purpose. If it runs to dozens of journeys it is a wish list. I agree it with Product, because Product knows which failures the business would have to apologise for, and I write each journey as an outcome a user can observe, the same way I would write acceptance criteria Product can sign. The list changes rarely. It is re-checked every release, whatever the diff looks like.
How to prioritise regression testing after a change
The second layer is change-based: what did this build touch? I map code, configuration and integration changes to the journeys they can reach. Release notes are a start. The better sources are the pull requests, the configuration and feature-flag diff, dependency upgrades, data migrations, and a direct question to the developers: what were you nervous about?
The size of the diff is a poor guide. A small change can still break checkout if the payment adapter moved, and a large one confined to a new screen may touch nothing old. Shared components, authentication, anything that formats money or dates and anything that talks to a third party get re-checked whenever they change, however small the change.
Change-based regression depends on being told what changed, and that is where it fails. The change I watch for is the one in nobody’s release notes: a configuration value edited directly on an environment, a third party that updated its side, a library bumped as part of something else. That is why the core runs regardless. It is the net under the map.
Put together, the strategy has four layers, and each answers one question.
| Layer | Question | How it is covered |
|---|---|---|
| Core journeys | What must still work? | The same short list every release, automated where stable and walked by hand on the surfaces people use |
| Change-based | What did this build touch? | Targeted checks on the journeys each change can reach |
| Exploration | What did the map miss? | Timeboxed sessions around the changed areas and their neighbours |
| Deferred | What are we knowingly carrying forward? | Named in the readiness note with an owner and something to monitor |
What to automate and what to check by hand
Automation guards what you already understand. A stable core journey with a clear oracle is a good candidate, and so are API checks on the integrations that journey depends on. What a suite cannot do is notice the thing nobody thought to assert, which is how a green run ends up sitting on top of a broken journey. I have written about that in When more automation hides a broken user journey.
Humans explore what changed and what the map missed. I timebox that work and aim it at the changed areas and their neighbours: the screens that share a component, a table or an API with whatever moved. The rest of the product is left alone.
I use AI to draft API checks in Bruno and performance scenarios in k6, because it is quick at the typing. The selection of what matters stays human. A tool can produce checks faster than I can read them. It cannot tell me which journeys the business would not forgive us for breaking.
What to do when you cannot cover everything
You never can, so say so. I timebox the regression effort, and whatever falls outside the box goes into the release readiness note as deferred: which area, why it was left, what could go wrong, who owns it and what will be monitored after go-live. The alternative is silent hope, and silent hope reads exactly like confidence until production disagrees.
- Changes: payment provider SDK upgraded. New copy on two onboarding screens. Session length changed in configuration.
- Core, every release: sign in, book, pay, receipt, cancel. Automated on web, walked by hand on iOS and Android.
- Change-based: each card type and a declined card on web and both apps. Refund. Session expiring in the middle of a payment.
- Exploration: 90 minutes on payment errors and on returning from the bank’s verification screen.
- Deferred: back-office reporting, untouched by this build. Risk: low. Owner: QA lead. Monitor: the nightly report job.
- Not run: the remaining 300 cases in the pack. Nothing in this build reaches them.
The objection: run everything to be safe
This is the one I hear most, and it sounds responsible. It fails for three reasons. A full run takes longer than the time available, so it gets rushed, and a rushed pass is worth less than a careful partial one. Old cases drift out of date, so some of what passes is checking behaviour nobody cares about any more. And a large pass count buries the question that matters this release: were the changed areas examined properly?
The opposite objection comes from Engineering: the change was tiny, so no regression is needed. The answer is the core list. It is short enough that running it is cheaper than arguing about it.
A good regression strategy feels boring. It asks the same four questions every sprint: what must still work, what changed, what evidence do we have, and what are we knowingly carrying forward. Once those have written answers, the conversation two days before release is about a specific risk that someone can accept or refuse, and the word “full” stops coming up.
Questions I get asked
Do you need to run full regression before every release?
No, and on most products you cannot. Run a short, agreed core of critical journeys every release, add checks based on what the build changed, explore around those changes by hand, and record what was left out with an owner. That gives better evidence than a rushed pass through a large pack whose cases may no longer reflect the product.
How do you decide what to include in regression testing?
Ask two questions. First, which journeys carry revenue, compliance or user trust? Those are checked every time. Second, what did this build touch? Map code, configuration and integration changes to the journeys they can reach and test around them. Anything outside both answers is a candidate to defer, in writing, with a named owner.
What should be automated in a regression suite?
Automate stable journeys with a clear expected outcome, and the API checks on the integrations they depend on. Leave newly changed areas and anything with a fuzzy oracle to a person until the behaviour settles. Automation confirms what you already understand, so it works best as a guard on the core and poorly as a substitute for exploring a change.
Filed under Release readiness and regression. Terms: Change-based regression, Exploratory testing, Regression testing, User journey.
