Executive Definition
Smoke testing is a shallow, broad set of automated checks that answers a single question: is this build stable enough to test at all? The term borrows from hardware engineering, where a newly assembled circuit was powered up and the technician watched to see if any component literally started smoking. In software, the equivalent is powering up a build and checking that the top-level flows do not immediately combust.
A smoke suite deliberately stays small. It runs three to ten critical-path scenarios — login, dashboard load, one write operation, one read operation, a health-check endpoint — and it finishes inside ten minutes. Anything longer breaks its purpose, because smoke exists to fail fast. If the smoke suite takes an hour, developers merge on top of broken builds and the whole gate collapses.
The output of a smoke run is binary. Either every scenario is green and the pipeline promotes the build into the next environment, or one is red and the pipeline halts. There is no yellow, no flaky-retry loop, no manual triage. Smoke tests earn the right to be blocking by being fast, deterministic, and covering only revenue-critical flows. If a smoke test is flaky, it does not belong in the smoke suite.
Smoke testing appears in three architectural layers. Post-build smoke runs immediately after compilation on the CI runner. Post-deploy smoke runs against the freshly deployed artifact in a real environment. Production smoke — sometimes called synthetic monitoring — runs on a schedule against live traffic to detect regressions that only surface with real data. Each layer answers a different question but they share the same discipline: shallow, broad, fast, blocking.
For QA engineers building or maintaining a smoke suite in 2026, the practical definition matters more than the historical one. A smoke test is any automated check whose failure justifies stopping the release train. Everything else — deeper functional coverage, edge cases, negative paths — belongs in regression or exploratory suites. Sharpen that boundary and your pipeline becomes trustworthy. Blur it and the smoke suite becomes another slow regression run that everyone learns to ignore.
Architecture & Production Code
A production-grade smoke pipeline has three parallel tracks feeding a single gate. Understanding the layout makes it easier to decide what belongs in smoke, what belongs elsewhere, and where flake will hurt you most.
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Git push │ ───▶ │ CI build & test │ ───▶ │ Smoke suite │
└─────────────┘ │ (unit + lint) │ │ (5–10 checks) │
└──────────────────┘ └────────┬────────┘
│
┌─────────────────────────┴────────────────────┐
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────────┐
│ Deploy to Stage │ │ Block merge / PR │
└────────┬────────┘ │ Post Slack alert │
│ └─────────────────────┘
▼
┌─────────────────┐
│ Post-deploy │
│ smoke (real API)│
└────────┬────────┘
▼
┌─────────────────┐
│ Promote to Prod │
└─────────────────┘The upstream tracks — unit tests, linters, static analysis — belong to the developer feedback loop. Smoke sits one step later, at the boundary between build artifacts and deployable systems. This placement matters: smoke runs against an assembled build, not against isolated modules, which is what makes it credible as a release gate.
The fan-out after the smoke suite is the design detail most teams get wrong. A green smoke run should trigger a deployment. A red smoke run should block the merge AND notify the on-call channel with a link to the CI run, the failing scenario, and the last passing commit. If you skip the notification step, developers rediscover failures by opening the CI dashboard voluntarily — which they rarely do.
Post-deploy smoke against a real environment is not optional in 2026. Container drift, environment-variable mismatches, and third-party API changes are common enough that a build passing pre-deploy smoke can still fail immediately in staging. Running the same smoke suite against the deployed artifact catches this class of failure before it ships to users.
name: Smoke
on:
pull_request:
branches: [main]
workflow_dispatch:
jobs:
smoke:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20, cache: npm }
- run: npm ci
- name: Boot app
run: npm run build && npm run start &
- name: Wait for health
run: npx wait-on http://localhost:3000/health --timeout 60000
- name: Run smoke suite
run: npx playwright test --grep @smoke --reporter=github,html
env:
BASE_URL: http://localhost:3000
- name: Upload trace on failure
if: failure()
uses: actions/upload-artifact@v4
with: { name: smoke-trace, path: test-results/ }
- name: Notify Slack on failure
if: failure()
uses: slackapi/slack-github-action@v1
with:
payload: |
{ "text": "Smoke failed on ${{ github.sha }} — ${{ github.event.pull_request.html_url }}" }Smoke vs Sanity vs Regression
| Aspect | Smoke | Sanity | Regression |
|---|---|---|---|
| Purpose | Build is stable enough to test | Specific change works | Nothing else broke |
| Depth | Shallow, broad | Narrow, focused | Deep, wide |
| Duration | ≤ 10 minutes | 10–30 minutes | 1–8 hours |
| Trigger | Every build | After a hotfix | Nightly / pre-release |
| Blocking? | Always | Usually | Depends on scope |
| Automation | 100% automated | Often manual | Mixed |
| Owner | QA + DevOps | QA | QA + product |
The three suites form a funnel. Smoke rejects broken builds cheaply, sanity confirms targeted changes, and regression sweeps for collateral damage. Skipping smoke to save time is the classic false economy — you pay for it in longer regression cycles run against builds that were never worth testing.
Production Debugging Scenarios
The failure modes below cover roughly 90% of smoke incidents observed in the pipelines audited during 2024–2026 SDET consulting engagements. Each has a clean fix, but the wrong fix — adding a retry — turns smoke into a slow, lying suite.
Smoke suite passes locally but fails in CI on cold-start latency
- Symptom
- First smoke run after deploy times out on /login; subsequent reruns pass.
- Root cause
- Serverless cold start or JIT warm-up exceeds the health-check timeout.
- Fix
- Add a warm-up curl against /health with wait-on before the suite starts; keep test-level timeouts tight.
Smoke green in staging, red in production within minutes of deploy
- Symptom
- Post-deploy smoke fails on a checkout endpoint that never appeared broken pre-deploy.
- Root cause
- Feature-flag defaults differ between staging and production configs.
- Fix
- Move flag defaults into a shared config file and add a smoke check that asserts the flag payload for each environment.
Smoke suite flakes on assertion order after a UI refactor
- Symptom
- The 'dashboard loaded' scenario fails ~5% of runs on element-not-found.
- Root cause
- Hard-coded wait was replaced with a chained locator that races the network request.
- Fix
- Switch to Playwright's expect().toBeVisible() with a network-idle wait or await the specific API response before asserting.
Practice this concept in a real QA interview
Run a live mock with our AI Interview Coach, tune your resume with the ATS Resume Reviewer, and screen live listings on the QA Jobs Radar.