Smoke Testing vs Sanity Testing: the Difference, Finally Clear
Smoke vs sanity testing: what each one is, when to run which, a side-by-side comparison table, and real examples from web and API projects.
Smoke and sanity testing get conflated because both are short, both are shallow, and both run before anyone does "real" testing. The confusion is mostly harmless — until a build fails and a team argues for two hours about which pass "counts". The distinction is simple once you anchor it to purpose: smoke testing asks "is this build stable enough to test at all?" while sanity testing asks "did this specific change do what it claimed?" Smoke is a gate on the build; sanity is a spot-check on the change.
Smoke testing: the build gate
The name comes from hardware: power on a board and watch for smoke before doing anything elaborate. In software, a smoke suite is a fixed, tiny set of critical-path checks — typically 5 to 15 cases — that must pass before anyone invests time in deeper testing:
- The app loads and renders its main screen (no blank page, no bundle error).
- A user can sign in with a known test account.
- The primary flow of the product completes (add to cart, submit the form, send the message).
- The main API endpoint responds with a valid payload.
Two properties matter more than the exact list. First, smoke suites are fixed — same cases every build, so "green smoke" is a comparable signal across builds, not a fresh judgment call. Second, smoke is pass/fail for the build itself: a smoke failure means nobody tests this build, full stop. Running a full regression pass on top of a failed smoke just manufactures bug reports about a build everyone already knew was broken.
Sanity testing: the change spot-check
Sanity testing is narrower and ad hoc. When a developer fixes one bug or ships a small change, sanity checks confirm the change works and its immediate neighbors did not break — before scheduling anything more thorough. It is usually unscripted, done by the tester who knows the area, in minutes:
- The login-timeout bug fix: verify the original repro now passes, plus one check that a normal login still works.
- A bumped dependency: one pass through the screens that library touches.
- A config change: the one endpoint it affects returns sane data.
Sanity fails fast on purpose: if the spot-check looks wrong, the change goes straight back to the developer without a formal bug lifecycle. If it looks right, the change becomes eligible for the broader regression pass.
Side by side
| Dimension | Smoke testing | Sanity testing |
|---|---|---|
| Goal | Is the build testable at all? | Is this specific change sensible? |
| Scope | Critical path across the whole app | Only the changed module/feature and its neighbors |
| Scripted? | Fixed, scripted suite, same every build | Usually unscripted, improvised per change |
| Trigger | Every new build or deploy | Every minor fix or small change |
| Who runs it | Automation or QA, right after build | Often the developer or the area's tester |
| On failure | Build rejected; deeper testing aborted | Change bounced back without a formal bug cycle |
| Typical duration | 5–30 minutes, automated where possible | Minutes, by hand |
| Analogy | Gate at the front door | Peek through the keyhole |
A note on regional vocabulary: some teams — following older textbooks — use "sanity" to mean the shallow build check and "smoke" for something else entirely. When you join a team that argues about the words, skip the dictionary fight and map the purposes instead: which check gates builds, which spot-checks changes. The ISO/IEC/IEEE 29119 testing vocabulary (ISO/IEC/IEEE 29119-1:2022) sidesteps both labels and classifies retesting by purpose and level — a useful tiebreaker in the naming debate.
Where each fits in the pipeline
The three-tier rhythm looks like this in practice:
- Build completes → smoke suite runs. Green? Testing proceeds. Red? Build is rejected and the regression pass never starts.
- Small change lands → sanity check. Developer or area tester verifies the fix and its immediate surroundings in minutes.
- Merge to main / nightly / pre-release → regression pass. The selected subset (or full suite) confirms nothing else moved. Smoke is the gate, sanity is the filter, regression is the insurance.
Teams that skip the smoke gate pay for it in the most expensive way possible: hours of regression results on builds that never had a working login. Teams that skip sanity funnel every typo fix into the full QA queue and drown it. The two short passes exist precisely to protect the long one.
Smoke suites and regression suites share cases — keep them in sync
Your smoke cases are a subset of your regression suite, extracted by priority. That means they obey the same quality bar: exact test data, observable expected results, stable IDs. If your cases are not yet at that standard, fix the foundation first — our guide on how to write test cases walks the anatomy with examples. And because smoke runs on every build, keep the checks honest with real data: the Fake Data Generator produces consistent test personas and payloads, so a smoke login never breaks because someone's fixture expired.
When a smoke or sanity check does catch a defect, it usually graduates into the suite as a permanent case — and if the finding needs a report, our bug report template keeps it actionable instead of dying in a chat message.
Related reading
- What Is Regression Testing? Techniques + a Reusable Checklist — the long pass that smoke and sanity exist to protect.
- How to Write Test Cases (Examples + Template) — exact data and observable results make automated smoke runs possible.
- How to Test JSON APIs Without Writing Code — quick sanity checks for API responses, no scripts required.