Nothing destroys trust in a pipeline faster than a flaky test: one that passes on one run and fails on the next, with nothing having changed. When the team starts clicking "re-run" by reflex, CI has become decoration.
Where flakiness comes from
- Timing: fixed
sleepinstead of waiting for a condition; race conditions. - Shared state: tests that depend on order or on data left behind by another test.
- Environment: network, clock, time zone, competing resources in CI.
- Uncontrolled randomness: random data without a seed.
How to fight it
- Wait for a condition, not for time. Use auto-wait / web-first assertions instead of
sleep(3000). - Isolate state. Each test creates and cleans up its own data; no order dependencies.
- Make time deterministic. Freeze the clock and fix randomness seeds.
- Quarantine. Mark the flaky test, take it out of the gate and open a ticket — don't let it "train" the team to ignore failures.
# Detect flakiness by running the same test many times
npx playwright test suspeito.spec.ts --repeat-each=20
A flaky test is worse than no test: it costs time and, little by little, teaches the team not to trust green.
Conclusion
Flakiness is quality technical debt. Treating it with the same seriousness as a production bug is what keeps the pipeline a source of truth — and not an obstacle to be worked around.