ProductHow it worksPricingBlogDocsLoginFind Your First Bug
Three release-stage gates, smoke, sanity and regression, each mapped to the single trigger that fires it: a new build, a targeted fix, or a pre-release merge
TestingSmoke TestingSanity Testing+1

Sanity vs Smoke Testing vs Regression: 3 Triggers

Tom Piaggio
Tom PiaggioCo-Founder at Autonoma

Smoke, sanity and regression testing are three separate release-stage gates, and the sanity vs smoke testing question people have is which one to run right now, not which is bigger. Smoke testing checks whether a build is alive: fast, wide and shallow, run first. Sanity testing checks whether a fix behaves as intended: narrow and deep, run after a targeted change. Regression testing checks whether anything else broke: the broadest and slowest of the three, run before release. Which gate fires depends on the trigger, not on a fixed suite picked in advance.

Every article on smoke vs sanity testing hands you a two-column table and a period at the end of the sentence. None of them tells you what to do the moment a build turns green, a fix lands, or a release window opens. That's the question that sent you here, answered below with a decision flow that names the trigger for each gate, not just another table.

This is for whoever is standing at that fork right now: the engineer watching a pipeline go green, the SDET who owns the release gate, the release manager deciding whether a build ships. It is not for the QA lead building a long-term suite-allocation strategy, and not for the reader asking whether an AI-generated suite tests anything real; those are answered elsewhere. Picking the inputs for one test case, a boundary value here, an equivalence class there, is one layer further down still. This page has one job: given the event that just fired, which gate do you run?

Smoke vs sanity vs regression: what each gate checks

Smoke, sanity and regression aren't three names for the same check run at different times. They check different things, on different triggers, at different depths, and mixing them up wastes either pipeline minutes or nerve.

Smoke testing asks one question: does the build come up? Log in, load the homepage, hit the core path, stop there. It's the shallowest and widest of the three, runs first, in seconds, and a failure means stop: don't run anything else against a build that can't clear the front door. That instinct isn't new: continuous integration has always depended on a fast first stage, what Martin Fowler calls the commit build, which he says should take only a few minutes. Smoke testing covers the full definition and a worked example suite, and a worked set of smoke test cases shows what that shallow pass actually contains.

Sanity testing asks a narrower question about one place: does the area a fix just touched behave as intended? It runs after a targeted change, in minutes, deep but narrow, and a failure means the fix is wrong or incomplete, not that the rest of the app broke too. Sanity testing covers the trigger-and-diff framing in full.

Regression testing asks the broadest question: did anything else break? It runs before a release or after a large merge, slowest and widest by design, because it covers ground the other two gates were never scoped to touch. A failure means a change had blast radius outside the surface it was meant to touch. Regression testing is the full guide; the automated regression testing guide covers what keeps that scope affordable on every merge.

Smoke testing vs sanity testing vs regression, across 5 axes

Here's the comparison most write-ups give you, minus the part where it stops at definitions.

SmokeSanityRegression
ScopeWidest, shallowestNarrowest, deepestBroadest, still deep
TriggerNew buildTargeted fixPre-release, large merge
DepthOne pass per core flowEvery path through changed areaEvery path across the app
CadenceEvery build, secondsAfter each fix, minutesBefore release, longest run
A failure meansStop, build isn't testableFix is wrong or incompleteChange had blast radius

Smoke test vs regression test, the pair that looks most alike

Both smoke and regression run wide across the whole app, which is exactly why people confuse them. What separates them is depth and trigger, not breadth: smoke goes one pass deep on every core flow and fires on a build, while regression goes every path deep and fires before a release.

Every axis points the same direction: smoke is fastest and shallowest, sanity is narrowest and most surgical, regression is slowest and broadest because it's the only gate checking for damage nobody predicted. None is more important than the others; they answer three different questions at three different moments, and running the wrong one at the right moment is how a bad build reaches production or a good fix gets stuck behind an hour of unrelated checks.

Which test to run when: each trigger and the gate it fires

The table above is honest, but it still leaves you doing the mapping yourself. Here's that mapping, stated directly, the thing most write-ups leave you to work out yourself:

Trigger-to-gate decision flowTrigger decides which gate runsTriggerGateNew buildSmokeTargeted fixSanityPre-release or large mergeRegression

The gate is a function of the trigger, not a fixed suite picked in advance.

Notice what actually decides the gate: not the size of the change, not how nervous it makes you, just the trigger. A build went green: run smoke. A fix landed for one bug: run sanity. A release window opened, or a large merge just landed: run regression. If you're running the wrong gate for the trigger in front of you today, that's the fix.

Scope versus depth: where smoke, sanity and regression sit

The three gates also separate along two dimensions at once: how much of the app they touch, and how deep they go into what they touch. Plotting that makes the shape of each gate visible in a way the table alone doesn't:

Scope versus depth: smoke, sanity, regressionThree gates, two shapesShallowDeepWideNarrowSmokeWide, shallowRegressionWide, deepSanityNarrow, deep

Smoke trades depth for width, sanity trades width for depth, and regression refuses to trade at all.

Regression sits in the corner that costs the most to run, because it's the only gate that doesn't get to specialize.

It has to be wide because a change anywhere can be the one that broke, and deep because a shallow pass would miss what a shallow smoke check is designed to accept. Smoke and sanity earn their speed by trading something away, width in sanity's case, depth in smoke's; regression never gets to make that trade, which is why the regression testing guide spends far more time on it than a comparison page needs to. The cost is real outside any one codebase, too: Google's own engineering team has written about being unable to regression test each code change individually, which produces exactly the kind of lag this section is describing, between a change landing and its test result coming back.

How Autonoma runs one suite at three scopes

Every gate above assumes a person curated it. Someone wrote the shallow login-and-load check that becomes the smoke suite, someone else wrote the narrow, deep pack scoped to checkout that becomes a sanity check, and a third person maintains the broad, slow suite that runs before release. Written that way, there are three suites, three owners, and three places for drift to creep in the moment the app changes and nobody updates all three.

We built Autonoma's agents to read the codebase directly instead of working from three separately maintained lists. Our agents derive test cases from the routes, components and flows that make up your app, the way a person would trace through the code to write a suite by hand, and our Diffs Agent keeps that derived suite current on every pull request by reading the code diff itself.

Because the suite comes from the code rather than from a person's memory of what each gate is supposed to cover, the same suite can run at three scopes depending on what triggered it: a build event runs the widest, shallowest slice as the smoke check; a diff-scoped event runs the deepest, narrowest slice over the changed area as the sanity check; a pre-release event runs the whole thing as the regression check.

That's not a claim that the three moments stop being distinct events; a build going green is still a different moment than a release window opening, and each still deserves its own pass or fail signal on its own timeline. What changes is what sits behind each signal: not three suites written by three people at three different times, but one regenerated, self-healing set of checks, sliced to a different scope depending on which trigger fired. One suite, three triggers, nothing left to quietly fall out of sync with the code underneath it.

One suite, sliced by triggerThe trigger picks the scope, not the suiteOne suiteFrom your codebaseNew buildSmokeWide, shallowTargeted fixSanityNarrow, deepPre-releaseRegressionWide, deep

The suite in the middle never changes; the trigger just picks which slice of it runs.

Where the split still matters, and where it stops

The habit of treating smoke, sanity and regression as three fixed, hand-authored suites was solid for the era that produced it. A person at a keyboard could only afford to write and run so many checks, so splitting the work into three different-sized suites, one cheap and shallow, one narrow and targeted, one comprehensive and slow, was the only realistic way to get reasonable coverage without rerunning everything on every change.

That's the assumption a gate like this used to run on: a curated, hand-maintained set of checks that a person kept updating by hand, run only when someone judged it worth their time. Once the checks behind a gate are derived from the codebase instead, and heal themselves automatically when the interface they check moves, the gate stops being a fixed suite someone maintains and becomes a signal you regenerate on demand, at whatever scope the trigger calls for. The scarce resource shifts too: it's no longer authoring or maintaining the checks, it's reviewing what a run actually surfaces.

If you're deciding whether this build ships right now, none of that changes what you do next: the trigger still tells you the gate. The re-architecture matters if you're asking why maintaining three separate suites used to cost what it cost, not if you're mid-incident deciding what to run next.

Where the split still matters is the trigger itself and the promise attached to it. A build going green still isn't the same event as a release window opening, and treating them as interchangeable, running the full suite on every commit or skipping straight to release with no smoke check, wastes either pipeline minutes or nerve. The three triggers aren't going anywhere. What stops holding is the assumption that a separately maintained suite has to sit behind each one.

What no gate here covers

None of the three gates above, however they're generated, cover every kind of testing a release needs. Exploratory testing, a person deliberately trying to break the app in ways no script anticipated, stays a human skill; no suite replaces someone actively hunting for the unexpected. A real-user beta catches failure modes only real devices and habits surface. Load and performance testing is a different discipline, concerned with behavior under volume, not whether one flow works once. Accessibility testing needs its own tools, ideally with people who rely on assistive technology testing the result directly.

Autonoma's agents sit inside this picture as the behavioral, end-to-end execution layer behind smoke, sanity and regression, not a replacement for the unit tests underneath them, the load rig running on its own schedule, or the accessibility scanner checking markup none of this touches. Smoke, sanity and regression tell you whether the application behaves the way the code says it should, not whether it behaves well for someone using a screen reader or holds up under heavy concurrent load, and no amount of codebase-derived test generation changes that boundary.

What the three gates cover, and what they don'tAutonoma runs theseSmokeSanityRegressionCodebase-derived, self-healingOutside the gatesExploratory testingLoad and performanceAccessibility testing

Autonoma runs the three code-derived gates; exploratory, load, and accessibility stay with people and dedicated tools.

Where regression testing goes deeper than this page can

Regression is the gate this page has the least room to do justice to, on purpose. It's the broadest of the three, and it's already covered by other posts on this site that go further than a comparison page needs to. The regression testing guide covers the full definition, the different strategies, and when each is worth the cost. The automated regression testing guide goes further still, into what keeps a regression suite affordable enough to run on every merge instead of once a quarter. If regression is the gate you landed here to understand in depth, start there.

None of that changes the question this page set out to answer. The next time a build goes green, a fix lands, or a release window opens, the gate is already decided: match it to the trigger, not to how big the change feels. That's true whether the suite behind each gate is hand-written and hand-maintained, or, like the one behind Autonoma, regenerated from the code itself every time it runs.

Frequently Asked Questions

Smoke testing checks whether a build is alive at all: the widest and shallowest of the three, run first, in seconds, on every new build. Sanity testing checks whether one specific fix behaves as intended: the narrowest and deepest, run after a targeted change, in minutes. Regression testing checks whether anything else broke: the broadest and slowest, run before a release or after a large merge. The three differ on scope, trigger, depth and cadence, and each one answers a different question rather than being a smaller or larger version of the same check.

Run sanity first. A sanity test checks only the area the fix touched, takes minutes, and tells you whether the fix itself is correct and complete. A full regression run is the broader, slower check that covers ground the fix wasn't meant to touch, and it belongs before a release or after a larger merge, not after every small, isolated fix. Running a full regression suite on every small fix burns time a sanity check would have caught the problem in already.

No. A failed smoke test means the build itself is not worth testing any further, stop and fix the build first. Running a full regression suite, or any other test, against a build that already failed its smoke check wastes the time regression testing needs, since a broken build will produce failures everywhere rather than pointing at the actual defect. Smoke has to pass before sanity or regression is worth running at all.

Yes, if the suite is generated from the codebase rather than hand-written and hand-maintained as three separate lists. When test cases are derived directly from an application's routes, components and flows, and kept current automatically as the code changes, the same underlying suite can run at three different scopes: a shallow slice across the whole app for smoke, a deep slice over just the changed area for sanity, and the full set for regression. What changes between the three is the trigger and the scope requested, not three independently maintained suites.

Autonoma runs one suite, derived from your codebase, at three different scopes depending on what triggered the run: a build event triggers the widest, shallowest slice as a smoke check, a diff-scoped event triggers the deepest, narrowest slice over the changed area as a sanity check, and a pre-release event triggers the full suite as a regression check. The suite is kept current automatically as the code changes, so there is no separate hand-maintained checklist behind each gate. Autonoma does not cover exploratory testing, load testing or accessibility testing; those stay with dedicated tools and people.

Related articles

Quara inspecting a single glowing lime panel on a control board while the surrounding panels stay dim, representing a narrow check after a targeted fix

What Is Sanity Testing? Checking the Fix That Shipped

What is sanity testing? A worked example: the narrow check on the changed rule, its two-item blast radius, and why the scope comes from the diff.

A balance scale weighing a manual smoke testing checklist and stopwatch on one pan against a stack of automated test files and maintenance tools on the other, with coins beside each pan

When Does Manual Smoke Testing Beat Automation?

Manual smoke testing wins in three specific cases. Here's the cost rule, runs per week times minutes per run against authoring plus maintenance, worked in full.

An isometric grid of dark tiles, several ringed in lime where an expected and actual check match, and one recessed hollow tile marking the check that failed, surrounded by shopping carts, pallets and a card reader

What Does Smoke Testing Actually Check?

What smoke testing is, why it runs first, and a worked four-check suite with an expected-vs-actual mismatch. Plus why smoke is a build property, not a list.

Two identical rows of test blocks run in different orders, one surfacing a failure early and one late, illustrating test case prioritization

Test Case Prioritization: Ordering a Suite You Can't Run

Test case prioritization orders tests that already exist and already made the cut. Four techniques, their failure modes, and why order now controls CI cost.