Flaky Test Quarantine: Owners, Expiry, and Nonblocking CI Results
A confirmed flaky test can block unrelated changes without providing a dependable release signal. Removing that obstruction is reasonable only if someone still sees…
A checkout test reports that the confirmation page never appeared. The failure could come from quantity validation, a payment response, a database write, or the page itself. Repeating every business-rule variation through that journey makes each failure expensive to investigate while leaving the underlying question unresolved: which part of checkout did this test need to prove?
The test pyramid is a model for distributing automated checks across different scopes. Its usual shape favors many focused unit tests, a smaller set of integration checks, and fewer end-to-end tests. The reasoning is that narrower checks often need less setup and identify failures more precisely, while broader checks supply evidence about connections that isolated tests cannot see. The shape is a heuristic, not a universal percentage target or a requirement to test every behavior through the same boundary.
Mike Cohn's original pyramid used unit, service, and user-interface layers. Modern discussions often use unit, integration, and end-to-end instead. Those labels are useful only when the team agrees what each test includes. Martin Fowler's explanation explicitly recognizes that the pyramid's cost assumptions have exceptions: broad tests that are fast, dependable, and inexpensive to maintain can justify a different balance.
For the checkout example, use these working definitions. Other teams may draw the boundaries differently; record the real components and replacements beside the test rather than relying on its folder name.
Layer | What Stays Real | Checkout Evidence | Important Evidence Gap |
|---|---|---|---|
Unit | A small, coherent piece of application behavior | Quantity acceptance or a payment-state decision follows the agreed rule | Does not establish real database, network, or deployment behavior |
Integration | Selected collaborating components and the boundary being examined | The checkout endpoint maps requests correctly and persists the intended order state | Does not establish every browser interaction or every external dependency |
End-to-End | The deployed application path across the declared journey | A customer can submit checkout and reach the correct observable outcome | Covers selected conditions, not every rule, configuration, or failure |
An API test can exercise one service or traverse several deployed services. A UI test can render one component with a fake backend or drive the complete application. The interface alone does not determine the level.
Playwright's official API-mocking example demonstrates this clearly: a route is fulfilled with a prepared response and the API is never called. A checkout page tested that way can establish how it displays an approved response. It cannot establish that the checkout service approved payment or saved an order, even though a real browser rendered the page.
Consider an illustrative checkout contract, not a customer case or a report of executed tests. The feature accepts an already-parsed integer quantity from 1 through 5, inclusive. Assume stock is available. A controlled payment response is either approved or declined. With valid quantity and available stock, approval confirms the order; a decline must leave it unconfirmed. Parsing, taxes, inventory contention, and duplicate-submission rules need separate specifications; they are outside this simplified contract.
The objective is to collect complementary evidence about this feature. Each layer should answer a question that its setup and observation points can support.
Exercise the quantity rule directly with 0, 1, 5, and 6. Under the stated contract, 1 and 5 are accepted; 0 and 6 are rejected. These values challenge both sides of the inclusive limits without starting a browser or database. They do not establish that every interior value works, that a request parser rejects decimal text, or that sufficient inventory exists.
Keep the expected result independent of the implementation. A test that derives its expected acceptance decision by calling the same validator again can agree with a faulty rule. Write the expectation from the contract, with a clear failure message identifying the input and violated limit. For a fuller method of selecting inputs, use black-box boundary and partition techniques.
A separate focused test can supply a declined payment outcome to the order decision and expect a non-confirmed state. An approved outcome should permit the contract's confirmed state. This establishes the decision logic under controlled inputs. It does not show that the payment adapter interprets the provider's actual messages correctly.
A unit need not be one private method or one class. It may be a function or a cohesive group of in-memory collaborators. Use real collaborators when they keep the behavior clear and dependable; use doubles where dependency control or isolation is necessary. A double is a substitute with assumptions, so identify which behavior it replaces and what remains unverified.
For a service-and-database integration test, run the real checkout request handling and application service against a test database. Apply the schema and configuration relevant to the check. Control the payment boundary so that an approval or decline can be reproduced safely, without live financial activity.
Submit a valid checkout request and inspect the stored order as well as the response. Check that the requested quantity reaches the record correctly and that its state matches the approved outcome. This can expose a missing field mapping or incorrect persistence behavior even when the quantity function passes all its tests.
For the declined case, assert the specified rejection response and verify that no confirmed order exists for that attempt. The contract might permit a separate record of a declined attempt; distinguish that from a confirmed purchase rather than assuming that every database table must remain empty. Use identifiers unique to the test so another run's records cannot satisfy the assertion.
A real test database supplies evidence about that engine, schema, and setup. An in-memory substitute may miss production-specific query, constraint, or transaction behavior. Choose the database scope around the suspected failure and document differences that remain. Passing against a test instance does not establish production capacity or every deployment configuration.
The payment adapter deserves its own boundary check. Give it representative provider responses and verify the application's mapping of approved and declined outcomes. A stubbed response checks the adapter against that example, not against a running provider. Validate the substitute's assumptions through suitable provider documentation, contract verification, or separately scoped sandbox checks. A sandbox still has limits and cannot prove that production credentials or all payment conditions are correct.
For the selected end-to-end checkout test, begin with a customer using the browser against a nonproduction deployment. Keep the application's routing, checkout service, and order database real. Declare whether the external payment boundary uses a sandbox or a controlled substitute. If the provider is replaced, the journey establishes application behavior up to that replacement, not a real payment settlement.
Prepare a known product, account, and valid quantity. Submit checkout, wait for the confirmation, and verify that its order identifier corresponds to the intended persisted order. Choose an appropriate observation interface for that environment. Confirmation text alone can pass while the application displays a response that was never committed to storage.
Retain a declined journey when browser handling adds important evidence: the customer should see the agreed rejection message and should not be presented with a completed purchase. There is no need to repeat every quantity or payment-rule permutation here if those variations supply no additional browser or wiring evidence.
Playwright's current guidance favors user-visible behavior, user-facing locators, and web-first assertions that wait for an expected condition. Those practices make the browser check more resilient, but they do not repair a weak expected result. Give the test independent data as well: isolated cookies and local storage do not automatically isolate orders stored by the backend.
A successful journey is evidence about its selected build, environment, account, and conditions. It does not establish zero risk or replace security, accessibility, performance, concurrency, and exploratory testing. Add those activities according to their own risks and observation needs rather than treating the pyramid as a complete quality strategy.
The same accepted quantity can appear at every layer without creating redundant tests. The unit test establishes the rule, the integration test establishes request and persistence mapping, and the E2E test establishes the selected deployed journey. Their inputs overlap, but their claims differ.
Duplication becomes costly when every quantity variation is repeated through the browser even though the extra runs only recheck the same acceptance decision. A rule change then creates several maintenance tasks and a wider failure report, without demonstrating another connection. Keep broad assertions focused on their additional evidence.
Ham Vocke's practical treatment of the pyramid recommends moving checks downward while retaining higher-level tests that add confidence unavailable below. Apply that recommendation to the failure mechanism, rather than forcing every defect into a unit test.
When a browser-only failure reveals a real checkout defect:
If the defect depends on deployment configuration, replacing that configuration with a convenient fake may remove the cause. A passing narrow test would then be weak evidence. Keep a targeted broader check or add an appropriate configuration test instead of shrinking scope solely to improve the diagram.
Test proportions are a poor target when teams count different things. A parameterized pytest function can run with several argument sets; reporting functions instead of collected cases changes the count without changing the tested behavior. Browser journeys may also contain several assertions. A tidy ratio can therefore conceal shallow checks or expensive duplication.
Measure the delays and failures your team experiences. Include environment provisioning, test-data setup, queueing, retries, and result investigation alongside execution duration. A short-running test that regularly blocks on a shared account may provide worse feedback than a larger check with controlled prerequisites.
Maintain a behavior map with the information needed to review placement:
A rules-heavy component may justify extensive unit coverage. A service that mostly translates requests and writes records may need a substantial integration layer. A rich frontend may need many focused UI component checks. None of those choices requires relabeling tests or adding low-value cases to reproduce an ideal silhouette.
Track intermittent failures separately from consistent passes. Playwright distinguishes a test that passes initially from one that passes after retry. Keep the first failure and investigate its cause; a later green attempt does not establish that the application or test was fixed. The relevant question is whether the check supplies dependable evidence at the time a developer or release owner needs it.
For the next checkout quantity-policy change, update the focused acceptance cases first. Inspect whether request parsing, serialization, or persistence also changes, and adjust the affected integration checks. Keep a selected E2E journey that proves the customer can still complete checkout, plus any high-value rejection path whose browser behavior needs verification. Do not copy the entire new boundary-input set into that journey by default.
Then decide when those results must arrive and who acts if they fail. A test automation strategy for scope, CI feedback, and ownership develops that operating decision beyond the layer definitions.
For each proposed test, write down what new failure it can expose and what remains outside its boundary. If the answer repeats evidence already supplied, narrow or remove the duplication. If an important connection has no credible check, add one at the scope that can observe it. The useful outcome is a portfolio that explains checkout behavior and its remaining uncertainty, not a prescribed ratio of test names.
A confirmed flaky test can block unrelated changes without providing a dependable release signal. Removing that obstruction is reasonable only if someone still sees…
A tester reviewing a Jira issue may need a fresh smoke run without opening GitLab and choosing pipeline parameters. A manually triggered Jira Cloud…
A regression-results worker receives HTTP 429 while reading Jira issues. Sleeping that worker may be necessary, but it will not help if other workers…
Create traceable test cases, prepare release-specific test runs, and keep approved coverage current as the product changes.