The AI testing era has added new test coverage myths without retiring the old ones. Teams still mistake line coverage for product confidence, then add agent-generated browser scenarios and mistake test volume for user-flow coverage. Neither number tells you whether the right customer can complete the right action under the right conditions, or whether a failure will produce evidence anyone can trust.
BrowserBash offers a useful lens because it starts from user intent. A plain-English objective drives a real Chrome or Chromium browser without selectors or page objects, then returns a structured verdict. Deterministic Verify steps can establish exact visible conditions. That makes user-flow coverage easier to express, but it does not make coverage automatic. You still need a risk model, controlled data, layer choices, review, and honest limits.
Test coverage myths: high line coverage means users are covered
Line coverage tells you which executable lines ran during tests. It does not tell you whether assertions were meaningful, whether combinations were exercised, whether permissions held, or whether a user could complete a journey. A service can reach 90 percent line coverage while its browser route is broken by a missing environment variable or inaccessible control.
Line coverage remains useful. Unexecuted code can reveal neglected branches, dead paths, and test gaps. The myth is treating it as a product-level confidence score. Ask what risk each test addresses and which observable behavior it proves.
A user-flow map starts with actors and promises. For a subscription product, examples might include a guest creating an account, a member upgrading, an owner downloading an invoice, and a canceled member losing premium access. Each promise crosses components and often includes states that line coverage cannot represent clearly.
Connect levels instead of competing them. Unit tests can exhaustively check price calculations. API tests can validate subscription transitions and authorization. Browser tests can confirm that the intended role can find, initiate, and observe the change through the integrated interface. Human exploration can investigate confusion and unanticipated paths.
The BrowserBash learning center explains objective-driven validation, but the product’s risk map must come from its team.
Myth 2: every requirement needs an end-to-end AI test
An end-to-end browser test is expensive in state, time, and diagnosis. Adding an AI agent can reduce selector choreography, but it does not eliminate networks, authentication, third-party systems, test data, or browser startup. Test a requirement at the lowest layer that can provide credible evidence, then add browser coverage only for integrated user behavior.
Pure functions belong in unit tests. API schemas and authorization rules need service-level checks. Exact keyboard behavior or DOM events may be clearer in conventional Playwright. BrowserBash is a strong fit when the user journey and real rendered page matter, especially where intent remains stable while UI implementation changes.
Use one browser flow to prove a representative integration, not every arithmetic combination. If twelve tax regions use the same UI and a tested service table, browser coverage for all twelve may add little. If one region changes required fields and disclosure text, that difference deserves its own flow.
AI also does not make very long objectives free. Small local models around 8B and under can be flaky on long multi-step journeys. Splitting the test at stable business boundaries improves evidence and makes the suite easier to own. Use a capable mid-size local Qwen3 model, Llama 3.3 70B-class model, or hosted model for genuinely difficult flows.
Coverage is the set of risks addressed across layers, not the count of browser cases.
Myth 3: generated scenarios are instant coverage
An agent can generate dozens of plausible scenarios from a feature description. Until a human confirms requirements, data, role, expected outcome, and failure meaning, those are ideas, not trusted coverage. Fluent prose can hide contradictory or invented assumptions.
Review generated tests as untrusted changes. Does the title state a user promise? Is the selected record unique? Is authentication safe? Are destructive actions isolated? Can the core outcome be expressed deterministically? Does the scenario duplicate a faster API or unit test?
BrowserBash’s importer demonstrates a more constrained kind of generation. browserbash import <specs-or-dir> heuristically converts common Playwright actions and expects without a model. It handles goto, click, fill, press, check, selectOption, getBy locators, and common expectations. process.env.X becomes {{X}}. Untranslatable material goes into IMPORT-REPORT.md rather than being dropped or invented.
browserbash import existing-playwright-tests
browserbash record https://preview.example.test
The recorder captures a manual flow in a visible browser and writes a plain-English test on Ctrl-C. Password values never leave the page; the generated step uses {{password}}. Both tools produce drafts. Review importer gaps, remove recorded detours, rewrite mechanics into intent, and add controlled outcomes.
Generated volume should feed a coverage backlog, not inflate the coverage score.
Myth 4: a passing agent verdict proves the whole objective
A verdict is only as meaningful as its assertions and state. An agent may reach a success page for the wrong record, interpret “looks correct” generously, or complete one acceptable path while skipping a business rule the author assumed was implicit.
BrowserBash 1.5.0 separates deterministic Verify assertions. Supported grammar compiles to Playwright checks for URL contains, title equals or contains, visible text, named buttons, links, or headings, element counts, and stored-value equality. Failures include expected-versus-actual evidence in run_end.assertions and Result.md.
Verify text outside the grammar still runs through agent judgment and carries judged: true. That is useful evidence, but it is not the same as a deterministic check. A coverage inventory should record whether the central promise is deterministic, agent-judged, manually observed, or inferred from another layer.
Use atomic checks and tie them to the seeded subject. Store an order ID during setup, operate on that order, and confirm the displayed ID and expected state. A generic “Order confirmed” heading alone may prove that some order completed, not the intended one.
Never fabricate a pass or benchmark. Coverage reporting should link to actual run history and assertion evidence, not a hypothetical verdict in documentation.
Test coverage myths: more tests always mean more flow coverage
Ten tests that all sign in as an owner and visit the dashboard may cover fewer risks than three tests across guest, member, and owner permission boundaries. Duplicate happy paths create maintenance and runtime without expanding the behavioral map.
Model flow coverage with dimensions:
| Dimension | Example values | Coverage question |
|---|---|---|
| Actor | guest, member, owner, support | Are meaningful permission differences exercised? |
| State | new, active, overdue, canceled | Are lifecycle transitions represented? |
| Action | view, create, update, delete | Are high-impact operations checked? |
| Outcome | success, denial, validation, recovery | Are both positive and negative promises proven? |
| Environment | local, preview, production read-only | Is integrated configuration covered appropriately? |
| Viewport | desktop, mobile | Does responsive behavior change the journey? |
Do not create the Cartesian product automatically. Use product risk to select combinations. A mobile-only navigation control may justify two viewport executions. A backend permission check with identical UI may not.
BrowserBash supports --matrix-viewport 1280x720,390x844 and labels each result in events, JUnit, and reports. A standalone viewport flag works on single runs. Apply these to meaningful responsive risks rather than doubling every test for a prettier matrix.
Myth 6: selector-free means maintenance-free
Natural-language intent avoids many locator and page-object changes. If a button moves or a table becomes cards while labels and behavior remain, an agent may continue successfully. That is real maintenance reduction, not elimination.
Tests still depend on product language, business rules, data, authentication, URLs, providers, models, and expected outcomes. A renamed concept may require updates across English tests. A new permission model changes scenarios. An expired session breaks navigation. An ambiguous instruction can become unstable as surrounding page content changes.
Avoid calling this blanket self-healing. BrowserBash uses agent interpretation and a replay cache. After a green run, the next identical run can replay actions with zero model calls, and the agent steps back in if the page changed. That mechanism can handle change, but teams still need to review whether the updated path proves the same promise.
Measure maintenance by hours and change causes, not locator counts alone. Track edits due to harmless UI structure, intentional requirement changes, test-data changes, model behavior, and infrastructure. Intent-based tests should reduce the first category while leaving legitimate semantic maintenance visible.
The feature overview helps set accurate expectations about current capabilities.
Myth 7: retries solve flaky coverage
A retry can distinguish a transient error, but automatic rerun-until-green converts uncertainty into a flattering report. A test that fails first and passes second still consumed time and produced inconsistent evidence.
BrowserBash process exit codes help separate categories: 0 passed, 1 validation failed, 2 error, infrastructure problem, or budget stop, and 3 timeout. Preserve every attempt and classify it. A deterministic text mismatch is different from browser startup failure. A timeout is not automatically an application regression.
run-all keeps history, detects flaky behavior, derives concurrency from CPU and RAM, and orders previously failed and slow tests first. Use its flaky signals as investigation pointers. Compare application and test revisions, model, provider, engine, viewport, auth, data, replay state, duration, and assertion type before assigning cause.
A flaky test does not provide stable coverage merely because one retry passes. Keep it advisory or quarantine it with an owner and review date. Continue collecting results so quarantine does not become invisibility.
Monitor mode alerts only on pass-to-fail and fail-to-pass transitions, never every green run. Those transitions are useful operational evidence, but environment or deployment changes can explain them. Correlate before labeling a test flaky.
Build a user-flow coverage model that teams can review
Start with business capabilities, then list actors, lifecycle states, high-impact actions, and promised outcomes. Link each risk to the best evidence layer. A simple registry can contain flow ID, description, risk, owner, test files, assertion type, environments, recent status, and known gaps.
Separate “specified,” “implemented,” “executed,” and “passing.” A flow can have a committed test that has not run against the current revision. A budget-stopped suite may skip it. A dashboard that marks every discovered file as covered misleads.
Include negative promises. Who cannot view, edit, approve, refund, or export? Include recovery: what happens after invalid input, an expired link, interrupted payment, or stale state? Include observability: does the user receive enough feedback to know what happened?
Use representative combinations based on risk and production usage. Document why excluded combinations are considered equivalent. Revisit that assumption after incidents, architecture changes, or new customer segments.
Store actual evidence. Agent-mode NDJSON provides machine-readable events. Result.md is human-readable. JUnit integrates with CI. The official GitHub Action uploads these artifacts and posts a self-updating PR verdict table; see its documentation.
Review the map with product, QA, engineering, security, and support. Coverage is a shared argument about risk, not a secret test-team percentage.
Govern cost and execution without shrinking truth
Coverage plans meet real budgets. BrowserBash version 1.5.0 includes a cost_usd estimate from a bundled per-model price table. Unknown models receive no estimate instead of a false one. run-all --budget-usd or --budget-tokens stops starting new tests after the suite crosses the limit, marks the rest skipped, exits 2, and writes spend into RunAll-Result.md and JUnit properties.
browserbash run-all tests/flows \
--shard 2/4 \
--matrix-viewport 1280x720,390x844 \
--budget-usd 2.50 \
--agent
Never count skipped tests as passing coverage. Report executed coverage and planned coverage separately. If a budget regularly stops required tests, reduce redundancy, move low-risk cases to a schedule, use replay or suitable local models, and adjust the budget transparently.
Sharding creates deterministic slices based on sorted discovery order, so parallel machines agree without coordination. Aggregate every shard before reporting execution. Missing shard artifacts should make coverage unknown, not green.
Cheap-model routing with --model-exec can plan on a strong model and execute on a cheaper one. Validate the resulting failure categories, not only cost. More retries and ambiguous actions can erase nominal savings.
When line, code, and user-flow coverage are useful
Use line and branch coverage to find unexercised implementation paths and guide code-level test review. Do not turn their thresholds into proof of user value. Use mutation testing where practical to assess whether assertions detect meaningful code changes.
Use API and contract coverage to represent endpoints, schemas, role rules, state transitions, and error cases. Use conventional browser automation for precise low-level interactions and stable coded fixtures. Use BrowserBash for readable integrated journeys where natural-language intent and real browser behavior add value.
Use manual exploratory coverage for novelty, usability, accessibility nuance, and unknown risk. Record charters, observations, and findings even when they do not become automation.
The decision is balanced, not ideological. If a selector-based Playwright test is stable, clear, and cheap, keeping it may be better than converting it. If a plain-English flow expresses the business promise more clearly and survives harmless UI churn, BrowserBash may be the better layer.
Read the BrowserBash blog for additional patterns, then build the mix around your evidence rather than a universal coverage percentage.
Audit coverage claims in pull requests and releases
Require a coverage statement to name what changed. “Covered by tests” is too vague. A useful note says which actor and state were exercised, which committed test ran, whether its core assertions were deterministic, which environment and viewport were used, and where the result artifact lives. It should also identify important adjacent risks that were not run.
For pull requests, map changed product areas to a focused smoke set and keep broader flows advisory. BrowserBash exit code 1 represents a validation failure, while 2 represents an error, infrastructure issue, or budget stop, and 3 represents timeout. A release report must not convert inconclusive runs into covered behavior. State “not executed” or “unknown” when previews expire, credentials fail, shards are missing, or the budget skips tests.
Review test changes beside product changes. A modified objective can expand, narrow, or redirect coverage even if the file name stays the same. Store the test revision with the result and avoid comparing runs as equivalent when the protected promise changed.
At release time, summarize gaps by business risk rather than by raw missing test count. “Owner invoice export on mobile was not executed because the provider timed out” supports a decision. “Coverage is 87 percent” does not explain what remains uncertain.
Use production incidents to refine user-flow coverage
Every escaped defect is a chance to inspect the model, not merely add another test. Ask whether the relevant user promise was absent, represented at the wrong layer, executed under the wrong role or state, asserted too weakly, skipped, flaky, or ignored. The answer determines the corrective action.
If an authorization defect escaped despite a browser test that only checked control visibility, add a service-level denial check and perhaps a direct-navigation browser case. If a mobile menu hid the only checkout action, add a targeted viewport flow instead of duplicating the entire suite at every size. If a copy change broke an exact assertion without harming behavior, narrow the assertion to the stable promise.
Record incident links in the flow registry and document which coverage assumption changed. Over time, incidents reveal which dimensions matter in your product. A B2B application may need richer role and lifecycle coverage, while a consumer application may need device, locale, and recovery coverage.
Do not claim that the new regression test makes recurrence impossible. It provides evidence for one encoded condition. Architecture changes, data combinations, and adjacent paths still require judgment.
Report coverage with confidence and limitations
Use a small set of honest measures: percentage of high-risk user promises with an owned test, percentage with deterministic core evidence on the current revision, recent execution status, unstable-test count, and known gap count. Show underlying names and results so the aggregate can be challenged.
Separate planned, automated, executed, passed, and trustworthy. “Automated” means an artifact exists. “Executed” means it ran in the relevant context. “Passed” means the recorded assertions held. “Trustworthy” adds stable history, controlled data, useful evidence, and ownership. These states prevent a newly generated file from appearing equivalent to a proven gate.
Add narrative limitations. State which browsers, providers, viewports, roles, integrations, and environments were not covered. Mention judged assertions and unknown model-cost estimates explicitly. A limitation is not an admission of failure; it is the information a release decision needs.
Retire stale flows. Coverage maps become misleading when removed features, renamed roles, and obsolete paths remain counted. A quarterly review should archive dead tests, merge duplicates, update owners, and reassess risks. The goal is a smaller truthful map, not perpetual growth.
FAQ
Does 100 percent line coverage mean an application is fully tested?
No. It means the measured lines executed, not that assertions were meaningful or user journeys, roles, states, integrations, and recovery paths worked. Use line coverage as one implementation signal inside a broader risk model.
What is user-flow coverage?
User-flow coverage maps important actors, starting states, actions, and observable outcomes to actual test evidence. It emphasizes business promises across layers instead of counting files or generated scenarios.
Do AI-generated tests increase coverage automatically?
No. Generated scenarios are candidates until humans validate the requirement, setup, safety, expected outcome, and best test layer. Only executed, reviewed evidence should influence a coverage claim.
Should flaky tests count as covered?
They should be shown as unstable, not silently counted as healthy coverage. Preserve every attempt, classify failure causes, and keep the test advisory or quarantined with ownership until its signal is trustworthy.
Replace a single coverage percentage with a reviewable flow-and-risk map. Install BrowserBash 1.5.1 using npm install -g browserbash-cli; an optional account supports cloud uploads, while local use requires none.