Flaky test: passes sometimes, fails sometimes; same code, same input. Root cause: hidden non-determinism.
Common causes:
- Time-dependence —
Date.today(),DateTime.now()— same input on different days = different results. - Race conditions — multiple async operations; order varies.
- External dependencies — test depends on network, external service availability.
- Order dependence — tests pass together but fail in isolation (or vice versa).
- Shared state — static variables persist between tests.
- Insufficient waits — UI test acts before page ready.
- Test data drift —
SeeAllData=truetests depend on org data.
Detection:
- Run tests 100x in CI; record failure rate.
- Compare passing vs failing logs to find difference.
Root cause analysis:
For each flaky test, ask:
- Time-dependent?
- Async / race condition?
- External dependency?
- Order-dependent?
- Shared state?
Fix patterns:
Time-dependent: Inject TimeService; mock current time.
apex public virtual class TimeService { public virtual DateTime getNow() { return DateTime.now(); } } // Test: provide mock TimeService
Async race: Add Test.startTest() / Test.stopTest() to flush. For UI tests, explicit waits.
External dependency: Mock instead of real call.
Order dependence: Each test sets up own data; no shared state.
Shared state: Reset static variables between tests.
Insufficient waits: Replace Thread.sleep() with explicit conditional waits.
Quarantine:
- If can't fix immediately, mark as flaky.
- Skip in CI but track.
- Don't block releases on flaky tests.
Process:
- Detect flaky tests.
- Triage — quarantine if blocking, fix if possible.
- Root cause systematically.
- Fix properly.
- Verify — re-run 100x.
- Remove from quarantine.
Common pitfalls:
- Ignoring flaky tests — erodes trust in suite.
- Retrying — masks the issue.
- Disabling without quarantine — lost forever.
- No process — flakies accumulate.
Senior QA insight: flaky tests poison the well. They erode developer confidence in the suite. Aggressively address them.
The senior framing: a flaky test is a broken test. Treat with same urgency as a failing test.
