Skip to content
the 5 kinds of flaky test i keep meeting, and what actually fixes them
article3 min read224 viewsAug 12, 2026

the 5 kinds of flaky test i keep meeting, and what actually fixes them

Siobhan O'Rourke@siobhan_tests

August 12, 2026 · 3 min read

#1 in Flaky Test Society

224 views5 comments

Ive been the person who gets pinged when CI goes red for about six years now, first in a fintech and now in insurance. After a while you notice the flakes arent random. They come in the same handful of flavours. Heres my list, roughly in order of how often I see them.

1. Racing the UI

The test clicks before the button is ready, or reads text before the request came back. The fix people reach for is a sleep. Dont. In Playwright use the locator assertions, they retry until the condition holds or the timeout hits:

await page.getByRole('button', { name: 'Get quote' }).click();
await expect(page.getByTestId('premium')).toHaveText('€42.10');

If you write expect(await locator.textContent()).toBe(...) you read it exactly once and youre back to racing. Thats honestly half the flakes I fix.

2. Tests that depend on each other

Test B only passes because test A created a user first. Run them in a different order, or in parallel, and B falls over. Check with --repeat-each=10 and --fully-parallel locally, if a test cant survive that it isnt independent. Every test sets up its own data, every time. Yes its slower. Its less slow than re-running the pipeline three times.

3. Shared test data

Two workers both create test@example.com and one of them gets a unique constraint error. Put something unique into every bit of data you create, the worker index plus a timestamp is grand:

const email = 'quote-' + test.info().workerIndex + '-' + Date.now() + '@example.test';

4. Time

Anything with "today", "next month", time zones or daylight saving. Our renewal tests used to fail one night a year (long story, ill write it up some day). Freeze the clock. Playwright has page.clock now so you can fix the time in the browser, and on the backend inject a clock instead of calling new Date() all over the place. Also run CI in a different time zone than your laptop on purpose, once, and see what breaks. Something will.

5. The environment itself

A slow shared staging database, a third party sandbox thats down, a container with half the memory of your machine. These look like flakes but they arent your tests fault. Mock third parties at the network level with page.route in UI tests, and keep a small separate suite that hits the real sandbox and is allowed to go red without blocking merges.

what i do with a flake on day one

  • Reproduce it with --repeat-each=50. Fails 1 in 50, you can fix it. Fails 0 in 50 locally, run it in CI with tracing on (trace: 'on-first-retry') and read the trace, its like a little flight recorder.
  • Quarantine it if its blocking people, but give it an owner and a date. A skipped test with no owner is a deleted test that hasnt admitted it yet.
  • Keep retries low. One retry in CI hides the odd blip and thats fine. Three retries hides real bugs. I watched a genuine race condition in payment code hide behind retries: 3 for months.

Thats it. None of this is clever. Its just boring consistency, which is most of QA if im honest.

Written by

Siobhan O'Rourke

QA automation lead at an insurance company in Dublin. Playwright, flaky test therapy, and asking "but what happens if the user clicks it twice". Sea swimmer.

Get the best of #flaky_test_society weekly

One email each Monday with the most useful posts. No spam; unsubscribe in one click.

Comments

5

Sign in to join the conversation.

Sign in to comment
Arjun Mehta@arjunmehta#3 in Flaky Test Society
The payment race condition behind retries: 3 is too real. We had a webhook test that was "flaky" for 2 months, it was actually a double processing bug. Saving this.
1 net votes
Siobhan O'Rourke@siobhan_tests#1 in Flaky Test Society
flaky tests are just bug reports with bad manners
0 net votes
Tunde Adebayo@tunde_ade#3 in Flaky Test Society
abeg who else just searched their repo for waitForTimeout after reading this. i found 31. thirty one
1 net votes
Marcus Johnson@marcus_oncall#2 in Flaky Test Society
point 5 is my whole life. half the "flaky tests" teams bring to me are the shared staging db being on fire. we gave every PR its own throwaway db and the flake rate dropped like a rock
2 net votes
Olivia Martin@liv_codes#3 in Flaky Test Society
my group project has 0 tests so technically 0 flaky tests. checkmate
1 net votes