zudo-test-wisdom
GitHub repository

Type to search...

to open search from anywhere

Quick Decision Table

Decision table and flowchart mapping what changed to the minimum testing level required, plus a symptom-to-pattern lookup for a failure already in front of you.

Use this table to determine the minimum testing level for your current task:

What ChangedMinimum LevelWhy
Pure logic / utility functionLevel 1No DOM or CSS involvement
Component props / stateLevel 2Need simulated DOM to verify output
Build config / template / SSGLevel 3Need to inspect built output files
CSS / layout / visibilityLevel 5CSS requires real rendering engine
Interactive UI flowLevel 4Need real browser for user interactions
Visual bug reportLevel 5Must see computed styles + visual result
"It's not showing"Level 5Visibility is a visual property
"It's still broken" (after test passed)Next level upCurrent level has blind spot for this bug
Canvas / photo-editor / zoom-resize surface where L4 is intractable AND L5 cannot reachLevel 6 (final resort)Neither E2E nor mechanical visual can express the assertion
Broken link / missing page / dead image / stale sitemapSite-integrity gates (L3/L4 hybrid)Structurally invisible to unit and component tests -- only a built-output/crawl check sees it
Deploy config: domain, route, binding id, certificatePost-deploy smoke testThe failure is not in the repository, so nothing that runs against the repository can see it -- only a request to the deployed origin can
Visual regression risk across a refactorCommitted-baseline visual regressionDeterministic pixel-diff gate -- catches shifted/recolored visuals an informal screenshot look would miss

Warning

"Minimum level" means the lowest level that can reliably catch the bug. Using a lower level gives false confidence -- the test passes, but the bug remains.

Decision Flowchart

flowchart TD A[What are you verifying?] --> B{Is it pure logic?} B -->|Yes| L1[Level 1: Unit Test] B -->|No| C{Is it component behavior?} C -->|Yes| D2{Verifiable with simulated events in jsdom?<br/>no real focus/scroll/navigation/hydration/browser APIs} D2 -->|No| L4[Level 4: E2E Browser Test] D2 -->|Yes| D{Does it involve CSS/visibility?} D -->|No| L2[Level 2: DOM Component Test] D -->|Yes| L5a[Level 5: Visual Verification] C -->|No| E{Is it build output?} E -->|Yes| L3[Level 3: Build Output Test] E -->|No| F{Is it interactive UI?} F -->|Yes| L4 F -->|No| G{Is it visual/CSS?} G -->|Yes| L5b[Level 5: Visual Verification] G -->|No| L1b[Level 1: Start with Unit Test] L4 -. L4 intractable AND L5 unreachable .-> L6[Level 6: AI-Based<br/>final resort, not for CI] L5b -. L4 intractable AND L5 unreachable .-> L6

The L2-vs-L4 discriminator: "component behavior" alone does not decide the level. If the behavior can be verified with simulated events in jsdom -- a plain dispatched event, no real focus, scroll, navigation, hydration, or other browser API -- it is Level 2. If it needs any of those real browser primitives, jsdom cannot simulate it convincingly enough to trust a passing test, so it is Level 4.

Key Principle: CSS Always Needs Level 5

Any change involving CSS, layout, or visual appearance should default to Level 5. This is because:

  1. Level 1 (unit tests) -- has no DOM at all, cannot process CSS

  2. Level 2 (jsdom) -- has a DOM but no CSS engine; getComputedStyle() returns default, cascade-less values -- no layout is performed and no stylesheet cascade is applied, so it cannot verify real CSS

  3. Level 3 (build output) -- checks file contents, not rendering

  4. Level 4 (Playwright) -- runs in a real browser, but a spec written the typical way asserts DOM state, not computed style or pixel output

This is a distinction about what the assertion checks, not what the tool can do: Playwright itself can assert computed styles (toHaveCSS) and take screenshots (toHaveScreenshot) just as deterministically as any Level 5 tool. A spec that asserts DOM state is doing Level 4 work; a spec that asserts computed style values or visual output is doing Level 5 work, whichever runner executes it. The rule stands regardless: CSS changes need Level 5-type verification.

Escalation Triggers

Move to the next level when:

  • Test passes but user says problem persists

  • You are testing logic but the bug might be visual

  • Lower-level test confirms data is correct but output looks wrong

  • You suspect a CSS or layout issue

  • Multiple lower-level tests pass but the feature does not work in the browser

The L6 Escalation Rule

Escalation to Level 6 (AI-based) is not part of the normal next-level progression. It requires both of these to be true at the same time:

  1. L4 is intractable. Writing a clean E2E for this surface is genuinely infeasible — canvas-driven, multi-camera/zoom, stateful resize transforms, or similar — not just "harder than usual."

  2. L5 cannot reach the assertion. There is no DOM element with a stable bounding rect, computed styles don't apply (the surface is <canvas>), and screenshot pixel-diff is too noisy.

If only one of the two is true, the right answer is the other level. L6 is the final resort, not "the next thing to try when L5 is hard."

Start from Your Symptom

The table at the top of this page starts from what you changed -- two of its rows (a broken link or stale sitemap, a visual regression across a refactor) are already symptom-shaped, so they aren't repeated below. When you are starting from what you are seeing instead -- a failure already in front of you -- start here. Each row points at the pattern page that covers that symptom.

SymptomStart here
A flaky E2E test -- passes most of the time, fails without a code changeFlake Root-Cause Catalog & Deflaking Recipe
A test reports green, but it never actually ranPlaywright Patterns § Guard against specs that match no project / the test.skip pass-by-skip trap
EADDRINUSE on a port nothing in your config claims to usePlaywright Patterns § The Hidden Auxiliary-Socket Port Race
Not sure whether to test against real D1 or a stubBackend & Node.js Testing § Mock the Binding, Not the Runtime
CI is green, but the published artifact is brokenPublishing-Pipeline Verification
A build that worked last month fails today with nothing in your own diffScheduled Re-exam & Night Exam § T3 as an External-Dependency Drift Net
It works on your machine but breaks on preview or productionEnvironment-Tiered Testing Against Deployed Targets
An absence assertion fails in CI only, and every positive assertion in the same test passesNegative Assertions vs. Their Own Fixture Data

After Choosing a Level: Decide Where It Runs

Picking the right testing level answers what the test can see. A second decision remains: where and when does the test run? That is the execution tier — and it is a separate axis.

  • Execution Tiers — defines T0 (inner loop) through T4 (local heavy lane), when each applies, and the migration rule for moving tests between tiers.

  • Heavy Test Decision Rule — the per-test procedure for a test that feels too heavy for PR CI: demote, delete, or classify by why it is heavy and assign the matching tier.

Revision History

CreatedUpdated