ON THIS PAGE ▾
A test that sometimes passes and sometimes fails on the same code is called flaky. One flaky test is an annoyance. A suite full of them changes how a team behaves: a red build gets a shrug and a re-run, someone says "probably flaky", and eventually a real defect goes through because nobody believed the failure.
That loss of trust is the real cost. Automation exists to give a dependable signal. Once people stop trusting it, you are paying to maintain a suite that no longer informs decisions.
Where flakiness comes from
- Timing and async behaviour. The test acts before the page or service is ready, or waits a fixed time that is sometimes not enough.
- Shared state and test order. One test leaves data behind that another depends on, so results change with the order they run in.
- Environment instability. Slow or overloaded test environments, shared services and network variation.
- Time and date dependence. Tests that assume a particular day, time zone or clock.
- Test data collisions. Parallel tests using the same records.
- Third-party calls. Real external services that are slow, rate-limited or briefly unavailable.
- Brittle locators. Selectors tied to layout or generated class names that change with every build.
Triage honestly
When a test fails intermittently, resist the urge to re-run until it goes green. Instead, ask which of three things it is.
- A product defect that appears only sometimes. A race condition in the product will look flaky in the test. Treat it as a real bug.
- A flaw in the test. Poor waits, shared data or a fragile locator. Fix the test.
- An environment problem. Instability outside both. Fix or isolate the environment.
A useful discipline is to reproduce before judging: run the test repeatedly in isolation and in the full suite and compare. A test that fails every time in one setting and never in another is telling you something specific.
Quarantine, with rules
Quarantining means continuing to run a flaky test while preventing it from failing the build. It is a sensible short-term move, and a dangerous long-term one, because a quarantined test no longer protects what it was written to protect. Make it safe with a few rules:
- Every quarantined test has a named owner and a ticket.
- Every quarantine has an expiry date; when it passes, the test is fixed, rewritten or deleted.
- The list of quarantined tests is visible on the build report, not buried.
- A test that fails consistently is a failing test, not a flaky one. Do not quarantine real regressions.
Fix the pattern
The most common single fix is replacing fixed waits with waiting for the condition you actually need. Modern test frameworks wait for elements to be ready automatically if you let them.
// Flaky: a fixed pause that is sometimes too short and always wastefulawait page.waitForTimeout(3000);await page.click("#submit"); // Steadier: act on what the user would act on, then wait for the outcomeawait page.getByRole("button", { name: "Submit" }).click();await expect(page.getByText("Order placed")).toBeVisible();Other durable fixes follow the same logic:
- Give each test its own data, created and cleaned up by the test itself.
- Stub or simulate third-party services in routine runs, and test the real integration separately.
- Use locators based on roles, labels or dedicated test identifiers instead of layout.
- Freeze or inject the clock for anything that depends on dates and times.
- Run the suite in a stable, consistently provisioned environment.
Keep the gate small and the signal clear
Not every test needs to block every build. A short smoke gate on each change, covering the journeys that matter most, followed by broader regression on a schedule, keeps feedback fast and keeps a failure meaningful. Track the flake rate over time; a rising trend is an early warning that trust is eroding.
Where AI helps, and where it does not
AI is well suited to grouping failures by signature, so that fifty failures with one cause appear as one, and to proposing a repair when a locator breaks because the interface changed. Both save real time. Neither removes the need for a person to decide whether a failure is a product defect or a test flaw, and to review each proposed repair, because an automatically "healed" locator can quietly start clicking the wrong thing.
THE UPDOER APPROACH
How UpDoer approaches this
In our methodology, automation is chosen deliberately at the strategy step, not assumed, and the same step records what stays manual. When we maintain suites, AI flags impacted areas, groups failures and proposes locator fixes; a QA engineer reviews each repair and decides whether a failure is a real defect or a test flaw. Reports show what was run and what was skipped, and the risk of skipping it, so a green build is a statement you can rely on rather than hope for.
See our Regression Testing, Web Application Testing and Mobile Application Testing services.
If you would like a second pair of eyes on your own situation, schedule a meeting and tell us about your product, your delivery process and the quality questions you are facing.