A flaky test passes and fails without a relevant product change. It wastes investigation time and weakens trust in the test suite. Teams eventually ignore failures, which allows real defects to reach users.
The correct response is not to rerun indefinitely. Treat flakiness as an engineering defect, preserve evidence and remove the underlying source of nondeterminism.
Identify timing assumptions
Asynchronous loading, animation and delayed API responses are common causes. Replace fixed sleeps with explicit waits for the state the test requires. Waiting only for element presence may be insufficient when an overlay still blocks interaction.
Capture screenshots and browser logs at the first failure. A retry that passes can otherwise destroy the most useful evidence.
Stabilise locators
Selectors based on generated classes, dynamic IDs or deep DOM paths break when presentation changes. Prefer unique, stable attributes or accessible labels agreed with the product team.
Verify that a locator identifies exactly one intended element. A broad selector may interact with a hidden copy on one run and the visible copy on another.
Isolate test data
Shared users, carts and records cause collisions, especially in parallel runs. Generate unique data per test or reset state through a supported API. Tests should not depend on another test having created or deleted a record.
Make cleanup safe and traceable. Cleanup that runs against a broad or uncertain scope can damage another test’s data.
Remove order dependence
Each test should establish its own prerequisites. A test that passes only after “create customer†ran first is not independent. Randomise execution order periodically to expose hidden dependencies.
Reset cookies, storage and application state according to the scenario. Reusing the browser can be faster, but it increases isolation risk.
Control environment variability
Record browser, driver, application version, operating system and test configuration. Resource constraints, network proxies and stale test environments can affect behaviour.
Use explicit readiness checks for deployed services. Do not start UI tests while the application is still migrating its database or warming critical components.
Investigate browser-specific failures
A test that fails only in one browser may reveal a real compatibility defect, different timing or unsupported interaction. Preserve the browser-specific trace. Avoid adding a conditional workaround until the application and locator behaviour are understood.
Run a focused cross-browser set before scaling the entire suite.
Watch for application defects
Not every intermittent failure belongs to the test. Race conditions, eventual consistency, duplicate requests and unstable APIs are product defects. Correlate test timestamps with server logs and network responses.
The test can expose a real reliability problem even if a manual retry succeeds.
Use retries as controlled evidence
A limited retry can reduce pipeline interruption while the team investigates, but mark the test as flaky and retain the first failure. Track retry rate by test and owner. Remove the retry when the cause is fixed.
Never count a passed retry as fully healthy. A rising retry rate is a quality signal.
Build a triage workflow
Classify failures by timing, locator, data, environment, browser or product. Record reproduction frequency, first failing build and evidence. Quarantine only when necessary, with an owner and expiry date.
Fix high-frequency and high-business-impact cases first. Delete tests that no longer protect a meaningful requirement rather than maintaining noise.
Practice exercise
Create a deliberately unstable test using a fixed sleep and shared account. Run it repeatedly, capture evidence and then repair synchronisation and data isolation. Report failure rate before and after.
Learn robust automation in the Selenium training at Softenant Technologies. Improve synchronisation with explicit Selenium waits and centralise stable interactions through the Page Object Model.
Final takeaway
Flakiness comes from uncontrolled timing, selectors, state or environment. Preserve the first failure, classify the cause and fix the assumption. Retries may contain disruption temporarily, but they do not create reliability.