Sanity vs Smoke Testing: When to Use Each (And When to Use Both)
"Sanity testing and smoke testing are the same thing." — every QA team that's never had a proper conversation about testing terminology.
They're not the same. They serve different purposes, trigger at different points, cover different scopes, and fail for different reasons. Conflating them leads to test suites that are either dangerously incomplete or exhaustingly slow.
Here's the definitive breakdown.
The One-Sentence Definitions
Smoke testing: A broad, shallow pass over the entire application to verify a build is stable enough for further testing.
Sanity testing: A narrow, focused pass over a specific feature or area to verify a targeted change is correct.
The metaphor: smoke testing checks whether the building is standing. Sanity testing checks whether the specific floor you just renovated is safe to occupy.
Origin of the Terms
Smoke test comes from hardware engineering. After assembling a circuit board, engineers would power it on and watch for smoke. If smoke appeared, they stopped — no point debugging software if the hardware is burning. In software, a smoke test is the equivalent "is this thing basically alive?" check.
Sanity check comes from everyday usage — "let me just do a sanity check on this before we proceed." In QA, it evolved to mean a quick verification that a specific change didn't introduce obvious problems.
Neither term has a formal IEEE or ISTQB definition, which is why they're so frequently confused. What matters is the operational distinction, not the etymology.
Detailed Comparison
Trigger Point
Smoke tests trigger after every build or deployment, regardless of what changed. New feature, bug fix, dependency update, configuration change — smoke tests run every time.
Sanity tests trigger after a specific targeted change. You've fixed a bug, updated a library, or tweaked a feature. Sanity tests run against the affected area.
Scope
Smoke tests cover the entire application, but shallowly. Login works. Dashboard loads. Primary navigation responds. API health endpoints return 200. That's it.
Sanity tests cover a specific feature or component, but more thoroughly. If you just fixed the checkout flow, sanity tests cover: adding items to cart, applying discount codes, processing payment, receiving confirmation email, updating order history. That's the whole checkout journey, not just "does the page load."
Purpose
Smoke tests answer: "Is this build worth investing further testing effort in?"
Sanity tests answer: "Is this specific change correct and hasn't broken adjacent behavior?"
Who Runs Them
Smoke tests are always automated and run by CI/CD. No human should be running smoke tests manually.
Sanity tests can be automated or manual. For stable, frequently-changed features, automate them. For new features or complex UI flows, a manual sanity pass by a QA engineer often catches more.
What Failure Means
Smoke test failure: The build is broken. Stop all testing. Nobody continues until smoke is green. This is a team-level blocker.
Sanity test failure: This specific change is broken. The developer who made the change needs to investigate. Other features and other team members can continue their work unblocked.
Speed Requirements
Smoke tests: Must complete in under 5 minutes. Under 3 minutes is better. This is a hard constraint, not a preference.
Sanity tests: Should complete in under 15 minutes for a focused feature area. They don't have the same urgency as smoke tests — they're verifying a change before it merges, not blocking the entire deployment pipeline.
Decision Framework: Which One to Run?
Use this decision tree:
A new build/deployment is ready
↓
Run smoke tests
↓
Smoke tests pass?
NO → Stop everything, fix the build, re-run smoke
YES → Continue
A specific change was made (bug fix, feature update, library upgrade)
↓
Run sanity tests for the affected area
↓
Sanity tests pass?
NO → The change is broken, don't merge/deploy
YES → Proceed to regression or full QAIn practice, both often run together in a CI pipeline:
- Build deploys to staging
- Smoke tests run (gate the deployment)
- Sanity tests run for changed areas (validate the specific change)
- If both pass, proceed to regression or production deployment
Practical Examples
Scenario 1: Bug Fix to Password Reset
Smoke tests: Run as always — login, dashboard, navigation. These verify the build is stable. The password reset bug fix shouldn't have broken these, but smoke tests confirm it.
Sanity tests: Run specifically on password reset — the fix scenario, the surrounding flow, the email delivery, the token expiration. These verify the specific fix is correct.
Scenario 2: Major Refactor of the Checkout Module
Smoke tests: Run as always. Checkout is included in smoke only if it's one of your top 5-10 critical paths (if checkout breaks, users can't pay — it should be in smoke).
Sanity tests: Not the right tool here. A major refactor warrants full regression testing on the checkout module, not just a sanity pass. Sanity testing is for targeted, small changes.
Scenario 3: Updating a Third-Party Payment Library
Smoke tests: Run as always — includes the basic checkout happy path if checkout is in your smoke suite.
Sanity tests: Run on payment processing specifically. Test successful charges, declined cards, refunds, webhooks. The library update could change behavior in subtle ways that your smoke test won't catch.
Scenario 4: Deploying a Configuration Change (Feature Flag)
Smoke tests: Run as always — verifies the application still starts and basic paths work.
Sanity tests: Run on the features controlled by the flag. Verify behavior with the flag on and off.
The "Just Run Regression" Trap
Teams often skip sanity testing and go straight to full regression after a change. The problem: regression suites take hours. For a small bug fix, you don't want to wait two hours to confirm the fix works.
Sanity tests give you confidence in minutes. You're not compromising quality by running sanity instead of regression — you're running the appropriate scope for the change. Full regression still happens on a schedule (nightly, pre-release), but sanity testing gives fast feedback on individual changes.
When NOT to Use Smoke Tests
Smoke tests are often overextended. Teams add tests until the "smoke suite" takes 30 minutes. At that point:
- Developers start skipping it
- CI pipeline becomes slow
- Failures in a 30-minute suite could be anything
If your smoke suite takes more than 5 minutes, it's a mini-regression suite masquerading as smoke. Cut it down. Move the deeper tests to regression. Keep smoke fast and shallow.
When NOT to Use Sanity Tests
Sanity testing doesn't work for:
- Large features: A new major feature needs full QA, not a sanity pass
- Cross-cutting changes: A database schema migration affects everything — sanity testing one area misses the rest
- Performance changes: You need load testing, not sanity testing
- Security changes: Requires dedicated security testing, not a quick sanity pass
Combining Them in a Pipeline
A practical CI/CD setup that uses both:
jobs:
# Always runs — gates the deployment
smoke-tests:
runs-on: ubuntu-latest
steps:
- name: Run smoke tests
run: npx playwright test --project=smoke
env:
BASE_URL: ${{ env.STAGING_URL }}
# Runs only for changed areas
sanity-tests:
runs-on: ubuntu-latest
needs: smoke-tests
strategy:
matrix:
area: ${{ fromJson(needs.detect-changes.outputs.changed-areas) }}
steps:
- name: Run sanity tests for changed area
run: npx playwright test tests/sanity/${{ matrix.area }}/Smoke tests gate the deployment. Sanity tests validate the specific changes. Together they give you fast, targeted feedback without running the full regression suite on every commit.
Summary
| Smoke Testing | Sanity Testing | |
|---|---|---|
| Trigger | Every build/deploy | After targeted change |
| Scope | Whole app, shallow | One area, deeper |
| Speed | < 5 minutes | < 15 minutes |
| Automation | Always | Often |
| Failure impact | Team blocker | Change blocker |
| Purpose | Build is testable | Change is correct |
Use smoke tests to gate every deployment. Use sanity tests to validate specific changes quickly. Use regression testing for comprehensive coverage. Don't use any of them as a substitute for the others.