Skip to content
Back to skills

Flaky Test Diagnosis

ASecurity

Turn a test that fails at random into one that fails on demand by controlling the seed, order, and clock. Use when a test passes on re-run, fails only in CI, or blocks a merge for reasons no one can reproduce.

  • 7 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 5, 2026
ai-agentsgoshelltesting

Security analysis

A100/100

Scanned September 5, 2026

npx -y skills add Amey-Thakur/AI-SKILLS --skill flaky-test-diagnosis --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Flaky Test Diagnosis?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Flaky Test Diagnosis
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/amey-thakur-flaky-test-diagnosis/badge)](https://www.skillsdirectory.com/skills/amey-thakur-flaky-test-diagnosis)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: flaky-test-diagnosis
description: Turn a test that fails at random into one that fails on demand by controlling the seed, order, and clock. Use when a test passes on re-run, fails only in CI, or blocks a merge for reasons no one can reproduce.
---

# Flaky test diagnosis

A flaky test is a test whose result depends on something it does not
control: a random seed, another test's leftovers, the wall clock, or thread
timing. The trap is re-running until it passes and calling it fixed, which
just hides the same nondeterminism from the next person. The job is to seize
the hidden variable until the failure becomes reliable, then remove it.

## Method

1. **Reproduce the failure in a tight loop first.** Run the single test
   hundreds of times: `pytest --count=500 path::test`, `go test -run X
   -count=500`, or a shell loop until it fails. A flake you can trigger 1 in
   50 locally is debuggable; one you only see in CI needs the environment
   pinned before anything else.
2. **Pin the random seed and read what it was.** Frameworks randomize:
   capture and print the seed on failure, then replay it. `pytest
   -p randomly --randomly-seed=<n>`, a fixed `random.seed(n)`, or
   `Random(n)` in the test. A failure that reproduces under one seed is a
   data-dependent bug, not cosmic flakiness.
3. **Shuffle and isolate test order.** Order-dependent flakes come from
   shared state one test leaves for another: a mutated global, an unclosed
   connection, a row not rolled back. Run the suite shuffled
   (`pytest-randomly`, `go test -shuffle=on`) to expose it, then run the
   suspect test alone; if it passes alone but fails in the suite, hunt the
   leaked state.
4. **Freeze the clock and time zone.** Tests that read `now()` fail at
   midnight, month ends, or on a slow machine where a timeout expires. Inject
   a fixed clock (`freezegun`, `libfaketime`, `Clock` injection) and set
   `TZ`. Replace real `sleep`-and-poll waits with deterministic waits on a
   condition, never a bare timeout tuned to a fast laptop.
5. **Quarantine external and timing dependencies.** Network calls, real
   filesystems, and unordered concurrency each add nondeterminism. Stub the
   network, use a temp dir per test, and await completion rather than
   sleeping. If concurrency is the source, the race-conditions skill applies
   to the code under test, not the test itself.
6. **Prove it with the same loop, then re-enable randomness.** The loop from
   step 1 must pass a long run with the fix in place. Only then remove the
   pinned seed and fixed order so the test guards real variation again. A
   test kept green only by freezing every input has stopped testing.

## Litmus tests

- Under one captured seed and fixed order, does the failure reproduce every
  run?
- Does the test pass alone and fail in the suite, or fail both ways?
- After the fix, does a 500-iteration shuffled loop stay green?

## Boundaries

Some flakiness is the code under test being genuinely nondeterministic
(unsynchronized threads, ordering assumptions on a hash map); fix the code,
not the test. Skipping or retrying a flake is a stopgap that hides real
races, and it belongs behind a tracked ticket, not in the merged suite.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…