A smoke testing example looks like this: log in with a known account, land on the dashboard, and confirm the workspace name renders in the nav. That single case, paired with checks on core create, core read, payment, and critical navigation, forms a shallow-but-wide smoke suite: the ten or so paths that confirm a build is alive enough to keep testing. Below: a filled suite for a real B2B SaaS app, a blank checklist template, and the three criteria for building your own.
If you're an engineer, SDET, or release owner staring at a "run smoke before we promote" ticket with nothing to run, here are the eleven cases: paste them into a spreadsheet or a test runner this afternoon, then use the reasoning behind them to write case twelve yourself. This isn't a suite-allocation strategy, an AI-test-trust debate, or boundary-value picking for a single case, those are a level down.
What a smoke test case actually is
A smoke test case checks the shallowest, widest slice of an app: the handful of flows that have to work for the build to be worth testing further. Smoke testing covers the full definition and the run-first framing; this page skips straight to the artifact. Smoke is deliberately shallow: it won't catch a miscalculated tax rate two screens deep or a race condition under load, that's sanity, regression, and non-functional territory. It answers exactly one question: is this build alive enough to keep testing, starting with the happy path.
A filled smoke suite for Ledgerly, a B2B invoicing app
Here's the suite, built and checked against a realistic B2B SaaS: Ledgerly, an invoicing tool with user accounts, a core "Invoice" object, and paid checkout through Stripe. Eleven cases across authentication, core create, core read, payment, and critical navigation. Every pre-condition enables its steps, and every expected result follows from them. The Actual Result column is intentionally blank, that's yours to fill in on the next run. The authentication cases stay smoke-level on purpose; a deeper login suite lives at test cases for the login page.
Authentication
| Case ID | Pre-condition | Steps | Expected Result | Actual Result |
|---|---|---|---|---|
| SM-01 | Account owner@acme.test exists with a known password; user is logged out | Go to /login. Enter owner@acme.test in Email. Enter the correct password. Click Log In | Redirect to /dashboard; top nav shows "Acme Co." as the workspace name | (fill in) |
| SM-02 | Same account exists; user is logged out | Go to /login. Enter owner@acme.test. Enter password "wrongpass1". Click Log In | Form re-displays on /login with "Incorrect email or password" | (fill in) |
| SM-03 | User is logged in as owner@acme.test | Click the avatar icon top-right. Click Log Out | Redirect to /login; visiting /dashboard directly redirects back to /login | (fill in) |
Core create
| Case ID | Pre-condition | Steps | Expected Result | Actual Result |
|---|---|---|---|---|
| SM-04 | Logged in as owner@acme.test; client "Beta Industries" already exists | Click New Invoice on /dashboard. Select Beta Industries in Client. Enter 1200.00 in Amount. Pick a due date 30 days out. Click Save Draft | Redirect to /invoices/{id}; status badge reads Draft; amount shows $1,200.00 | (fill in) |
| SM-05 | Logged in; no client named "Gamma LLC" exists yet | Click Clients in the left nav. Click Add Client. Enter Gamma LLC in Company Name. Enter billing@gamma.test in Email. Click Save | Redirect to /clients; Gamma LLC appears with the entered email | (fill in) |
Core read and list
| Case ID | Pre-condition | Steps | Expected Result | Actual Result |
|---|---|---|---|---|
| SM-06 | Workspace has exactly 3 invoices across Draft, Sent, and Paid | Click Invoices in the left nav. Read the table | All 3 rows render a client name, amount, and status badge; no row is blank or "undefined" | (fill in) |
| SM-07 | Invoice INV-1042 exists, status Sent, with 2 line items | From /invoices, click row INV-1042. Read the detail page | Both line items render; subtotal, tax, and total match the list-view amount | (fill in) |
Payment and checkout
Both cards below are from Stripe's published test cards, so they work against any Stripe sandbox.
| Case ID | Pre-condition | Steps | Expected Result | Actual Result |
|---|---|---|---|---|
| SM-08 | Invoice INV-1042 status is Sent; Stripe sandbox card 4242 4242 4242 4242 is configured | Open INV-1042. Click Pay Now. Enter card 4242 4242 4242 4242, exp 12/29, CVC 123. Click Submit Payment | Page shows Payment Successful; status badge updates to Paid within 5 seconds | (fill in) |
| SM-09 | Invoice INV-1043 status is Sent; Stripe test decline card 4000 0000 0000 0002 is configured | Open INV-1043. Click Pay Now. Enter card 4000 0000 0000 0002, exp 12/29, CVC 123. Click Submit Payment | Error banner reads "Your card was declined"; status stays Sent; no charge recorded | (fill in) |
Critical navigation
| Case ID | Pre-condition | Steps | Expected Result | Actual Result |
|---|---|---|---|---|
| SM-10 | User owner@acme.test belongs to two workspaces, Acme Co. and Acme EU | Click the workspace name in the top nav. Select Acme EU | Reload to /dashboard; top nav reads Acme EU; invoice list shows only Acme EU data | (fill in) |
| SM-11 | Logged in as owner@acme.test, workspace owner role | Click the avatar icon. Click Settings. Click the Billing tab | /settings/billing loads; current plan name and next invoice date are visible | (fill in) |
Five categories, sized by need, add up to eleven cases.
The reusable smoke test template and checklist
Ledgerly's suite is one instance of a shape that repeats across most B2B apps. Swap in your own account, object, and buttons, and this blank checklist drafts your own smoke suite in under an hour.
| Case ID | Pre-condition | Steps | Expected Result | Actual Result | Pass/Fail |
|---|---|---|---|---|---|
| SM-01 | Name the account and starting state authentication needs | List the login page, fields, and the exact button clicked | State the page and the element that confirms success | (fill in) | (fill in) |
| SM-02 | Name the record your core object needs to already exist | List the create form's fields, values, and save action | State the redirect and the field that proves it saved | (fill in) | (fill in) |
| SM-03 | Name how many records must exist to test the list view | List the nav click that opens the list or detail page | State what must render, and what "blank" would mean | (fill in) | (fill in) |
| SM-04 | Name the record and payment state checkout needs | List the checkout fields, test payment details, and submit action | State the success state and the status field that flips | (fill in) | (fill in) |
| SM-05 | Name the role or membership critical navigation needs | List the exact clicks through the nav or menu | State the destination page and one element that confirms it | (fill in) | (fill in) |
| SM-06 | Your sixth critical path, named by the criteria below | List its fields, buttons, and clicks in order | State the exact page state that proves it worked | (fill in) | (fill in) |
How Autonoma turns your critical paths into a smoke suite
Every one of the eleven rows above was written and checked by hand, and will need updating by hand the day Ledgerly adds a second payment method or renames a button. That's the real cost of a smoke suite: not the first afternoon of writing it, but every afternoon after, when the UI moves and the suite either gets updated or quietly stops testing what it claims to. This gate was a curated, hand-maintained suite when a human ran each check. When the checks are derived from the codebase and healed automatically, the gate stops being a list you maintain and becomes a signal you regenerate, and the scarce work moves from writing the rows to reviewing the one that failed.
That's the architecture we built Autonoma around. Connect a codebase and it reads the routes, forms, and flows a human would walk to build the table above, planning cases from them and generating the endpoints needed to seed the database into the state each one needs (an invoice in Sent status, a client that doesn't exist yet). It drives those cases against a live preview environment and classifies what comes back as a real bug, an agent error, or a plan mismatch. The architecture is built around a Diffs Agent meant to read a pull request's diff and keep cases current as the app changes, rather than freezing as a snapshot from three sprints ago. None of this is a benchmark claim, it's architecture: reading the code and verifying through the running application.
Autonoma plans cases from the code, runs them on a preview, and classifies what comes back.
How to choose your own smoke test cases
The suite above covers five categories because most B2B apps have five categories worth guarding. Your app might need six, or four. The question isn't how many rows to fill, it's which flows earn a row at all, and that comes down to three criteria applied together, not any single one.
Highest-traffic asks which paths most sessions touch, usually login and the primary list view. Revenue-blocking asks which paths sit between a user and money changing hands: checkout, upgrade, invoice payment, where a bug stops the business instead of just annoying someone. Unrecoverable-if-broken asks which paths, if silently wrong, corrupt data or block everything behind them; a broken workspace switch or a create form that silently drops a field is worse than a crash, because nobody notices until support tickets pile up.
A flow that scores on one criterion might still be a regression case; one that scores on two or three almost always belongs in the suite. Walk your app's sitemap once, score each flow against the three, and keep only the ones that clear at least two. That's the hour of work the checklist above drafts.
A flow in one circle is a regression case; where two or three overlap is the smoke suite.
Where the smoke gate sits in your pipeline
Smoke is the first gate, not the only one: it runs right after a build promotes, before sanity, system, or regression get a turn, a sequence covered in how the smoke, sanity, and regression gates differ, since there's no point running a longer suite against a build that can't clear the shallow one. Wiring it into CI as a job that blocks a bad promote is covered in automated smoke testing; once green, it's one row in the larger release readiness checklist that decides whether the build ships.
Smoke is gate one; a fail routes back to the developer before sanity, system, or regression run.
The suite was never the eleven cases
Here's the re-derivation. Anyone can copy the eleven rows above into their own repo and rename Ledgerly to their own product. That's useful for an afternoon. But the value here was never the specific rows, it was the criteria that picked them: highest-traffic, revenue-blocking, unrecoverable-if-broken, applied to a real sitemap. A hand-written smoke list encodes that judgement once and then hides it. Six months later, nobody can say why login and checkout made the cut but settings didn't, and the suite calcifies or gets padded with unscored cases.
That's exactly the input a generator needs, and exactly what a static checklist leaves implicit. Say the criteria out loud, in a sentence a teammate or a tool can apply the next time the app grows a feature, and the suite stops being a relic of the day someone sat down and wrote it. It's also why Autonoma asks a connected codebase for its routes and flows instead of asking a person to click through the app first: the criteria are the input either way, a human just used to be the only thing that could apply them. Hand those criteria to something that reads the codebase on every change, and the eleven rows stop being a document you keep patching and become output you regenerate, which is exactly what connecting a repository to Autonoma turns them into: a smoke suite that re-derives itself the day Ledgerly grows a twelfth critical path.
Frequently Asked Questions
The eleven cases above and the checklist that generalizes them cover most of what comes up when building a first smoke suite. A few questions keep recurring.
A smoke test example is a check on one of the shallowest, most critical paths in an app, such as logging in with a known account and confirming the dashboard loads with the correct workspace name in the nav. A full smoke suite pairs that with checks on core create, core read, payment or checkout, and critical navigation, typically eight to fifteen cases total covering the paths that have to work for a build to be worth testing further.
Most smoke suites land between eight and fifteen cases. Fewer than that usually means a critical path, often payment or account creation, is missing. More than fifteen usually means the suite has drifted into sanity or regression territory, checking depth rather than breadth. The three selection criteria, highest-traffic, revenue-blocking, and unrecoverable-if-broken, are a better sizing signal than a target number.
A smoke test case checks that a critical path still works at all, run first and kept shallow on purpose. A regression test case checks that a specific area still behaves correctly after a change, and regression suites are deliberately broader and deeper than smoke suites. The two often share a flow, such as login, but a regression case for login might also verify session timeout and password reset, where the smoke case only confirms the dashboard loads.
Not the whole suite, but you do need to revisit it whenever a critical path changes shape, a new one appears, or an old one gets removed. Teams that never revisit their smoke suite tend to keep testing features nobody uses anymore while a genuinely revenue-blocking flow added last quarter never gets a case. Re-scoring the app against the three selection criteria once a quarter catches both problems.
Yes. Autonoma reads a connected codebase and plans test cases directly from the routes, forms, and flows it finds, including the database state each case needs, which is the same input the three selection criteria of highest-traffic, revenue-blocking, and unrecoverable-if-broken are meant to produce by hand. It runs those cases against a live preview environment and classifies what comes back, and the architecture is built around a Diffs Agent meant to keep the suite current as the code changes. It doesn't replace deciding which paths are revenue-blocking for your business, that judgement still starts with a person; it replaces re-writing and re-maintaining the rows once that judgement is made.
Score each candidate flow against three criteria, highest-traffic, revenue-blocking, and unrecoverable-if-broken, and only write a case for flows that clear at least two of them. Then fill five columns for each one: pre-condition, the exact account or record state that has to exist first; steps, the specific fields, values, and buttons clicked in order; expected result, the exact page, element, or status that proves it worked; actual result, left blank until the case runs; and pass or fail, marked once it does. Skipping straight to steps without a pre-condition or expected result is the most common reason a smoke suite turns flaky.




