agentsclimarketplace

Flaky test diagnosis

Skill Amey-Thakur/AI-SKILLS/skills/debugging/flaky-test-diagnosis

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.From its SKILL.md

Install
npx -y skills add Amey-Thakur/AI-SKILLS --skill flaky-test-diagnosis

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 23 days oldThe repository was created 23 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.1 KB, 732 tokens by cl100k_base, as published. Nobody here has run it

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.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,851. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.