本文へ移動
cccskills
無料GitHub で公開

flake-pattern-reference

Reference catalog of the eight flake patterns - async/timing, test ordering, shared parallel state, resource leaks, network, locator drift, environment variance, randomness - with detection heuristics, remediation per pattern, and the concrete code-level fixes: replacing fixed sleeps with framework auto-waits, isolating state in beforeEach fixtures, per-worker DB schemas via workerIndex, try/finally teardown, mocking network + clock at the boundary, stable role-based locators, TZ pinning, and RNG seeding. Use when triaging an unknown flake to identify the category before bisecting, or when a classified flake needs the specific code change to apply.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qaスター 13(GitHub 13 + cccskills 0)
連携ツールPlaywright

実行スコア 未検証

インストール方法を見る

含まれるファイル(25)

  • SKILL.md15.0 KB
  • .tessl-plugin/plugin.json795 B
  • evals/api-test-port-collision/criteria.json4.0 KB
  • evals/api-test-port-collision/task.md4.2 KB
  • evals/archive-write-race/criteria.json3.9 KB
  • evals/archive-write-race/task.md3.3 KB
  • evals/due-date-boundary/criteria.json4.6 KB
  • evals/due-date-boundary/task.md3.1 KB
  • evals/import-job-fixed-wait/criteria.json3.7 KB
  • evals/import-job-fixed-wait/task.md3.6 KB
  • evals/inventory-fixture-collision/criteria.json4.4 KB
  • evals/inventory-fixture-collision/task.md3.2 KB
  • evals/leaked-clock-stub/criteria.json4.3 KB
  • evals/leaked-clock-stub/task.md3.6 KB
  • evals/profile-completion-order/criteria.json3.8 KB
  • evals/profile-completion-order/task.md3.3 KB
  • evals/repository-pool-exhaustion/criteria.json3.8 KB
  • evals/repository-pool-exhaustion/task.md4.8 KB
  • evals/session-precondition-dependency/criteria.json4.3 KB
  • evals/session-precondition-dependency/task.md3.2 KB
  • evals/shared-cart-fixture/criteria.json3.9 KB
  • evals/shared-cart-fixture/task.md3.2 KB
  • references/environment-and-randomness-fixes.md3.7 KB
  • references/network-and-locator-fixes.md3.6 KB
  • references/timing-and-isolation-fixes.md6.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

flake-pattern-reference

Terminology note: "flaky test" is a practitioner-emergent term popularized by the Google Testing Blog (google-causes, google-flaky); ISTQB does not maintain a canonical entry. This catalog reflects industry-engineering consensus, not ISTQB authority.

A flake is rarely random - it almost always falls into one of eight recurring patterns. Identifying the pattern early shrinks the bisect search space dramatically. This catalog is a reference, not a workflow; the matching workflow is in flaky-test-quarantine.

The Google Testing Blog observed a near-linear correlation between test size and flakiness rate across ~4.2M tests (google-causes) - larger tests touch more of the eight patterns at once.

Pattern 1: async / timing

The most common flake category in UI and integration tests.

SignalWhat's happening
Fails ~5 - 20% of runs; passes when the machine is fasterTest waits for an arbitrary setTimeout(N) instead of a deterministic event.
Fails on CI but never locallyCI runners have different cold-start timings than dev laptops.
Fails after a dependency upgrade with no test code changeLibrary's internal timing changed (e.g. Playwright auto-wait window).

Remediation:

  • Replace fixed sleeps with deterministic waits - await expect(loc).toBeVisible(), page.waitForLoadState('networkidle'), page.waitForFunction(...), etc.
  • For animations, disable them in test setup (animations: 'disabled' in Playwright; Cypress.config('animationDistanceThreshold', 0) in Cypress).
  • For absolute clock dependencies, freeze time with sinon.useFakeTimers() / vi.useFakeTimers() / Playwright's page.clock.install().

Pattern 2: test ordering

Tests pass alone, fail when run with siblings.

SignalWhat's happening
npm test -- --testNamePattern='^X$' passes; full run failsTest relies on state from a previously-run test.
Adding a new test breaks an unrelated existing oneImplicit ordering dependency exposed by the new test pushing the old test into a different position.
Random-order test runners (Jest randomize) flag the suiteSuite is order-dependent.

Remediation:

  • Run the suite with explicit randomization in CI to surface ordering deps early (jest --randomize, pytest --random-order, mocha --sort reverse).
  • Move ANY shared setup into beforeEach / afterEach, never rely on beforeAll for state that the test mutates.
  • Database tests: roll back transactions after each test instead of truncating between describe blocks.

Pattern 3: shared parallel state

Tests pass sequentially, fail when run in parallel workers.

SignalWhat's happening
Fails ~50% of runs in CI matrix; passes locally with -j 1Two workers writing to the same DB row / file / port.
Fails more often as worker count goes upLinear shared-state contention.
Error message mentions "duplicate key" / "address in use" / "file already exists"Direct collision evidence.

Remediation:

  • Find the shared state two workers collide on - DB rows, files, ports, or global module state.
  • Per-worker isolation: per-worker DB schemas (PG_SCHEMA=test_${WORKER}), per-worker temp dirs (TMPDIR=/tmp/test-${WORKER}), per-worker port ranges.
  • For unique IDs: use UUIDs or a per-worker namespace prefix, not auto-increment integers shared across workers.

Pattern 4: resource leaks

Tests pass on a fresh machine, fail after the test process has run for hours.

SignalWhat's happening
Fails increasingly often as suite duration growsMemory or file-descriptor leak in the test setup.
EMFILE / EADDRINUSE errors mid-suiteFile-descriptor or port exhaustion.
Long-running processes (Playwright browsers, Cypress runners) crash mid-suiteProcess accumulating zombies.

Remediation:

  • Always await browser.close() / await server.close() in afterAll, with a try/finally so failed tests still clean up.
  • Set per-test timeouts and ensure the framework kills the process, not just the test (--testTimeout, test.setTimeout()).
  • Run lsof | wc -l and ps aux | wc -l before / after the suite in CI to detect leaks; alert when growth exceeds a threshold.

Pattern 5: network / external service

Tests pass when the upstream is healthy, fail otherwise.

SignalWhat's happening
Fails on the same handful of tests that hit the same external URLReal network call to a flaky third party.
Fails right after a deploy of a non-test serviceTest is hitting prod / staging of a sibling service.
ETIMEDOUT / ECONNRESET in error logsNetwork-layer error, not test-logic error.

Remediation:

  • Mock at the boundary - never let test code reach a real network endpoint. Use Mock Service Worker (MSW), nock, WireMock, or Playwright's page.route().
  • For tests that must hit a real service (smoke / contract tests), isolate them in a separate suite that doesn't gate the main CI.
  • DNS-level: pin to specific resolvers in CI to avoid resolver variance.

Pattern 6: locator drift

UI tests pass when the page looks one way, fail when it shifts.

SignalWhat's happening
Fails after an unrelated CSS changeSelector matched by position rather than identity.
selector matched 2 elements errorsAmbiguous selector now matches more than one node.
Fails only at certain viewportsLayout shifts cause mobile / desktop selectors to differ.

Remediation:

  • Use role-based selectors first (page.getByRole('button', { name: 'Submit' })), then data-testid, only text= / CSS as a last resort.
  • For Playwright: enable strict: true so any ambiguous selector fails immediately rather than silently picking the first match.
  • For viewport-specific UIs: snapshot at every breakpoint via the breakpoint matrix in playwright-snapshots; visual signal exposes layout-shift flakes faster than text checks.

Pattern 7: environment variance

Tests pass on Linux CI, fail on macOS dev machines (or vice versa).

SignalWhat's happening
Fails only on a specific CI runner / OSOS-specific path separator, line ending, or filesystem case sensitivity.
Snapshot tests fail with sub-pixel diffs across OSOS font / anti-aliasing differences (see playwright-snapshots).
Fails in tz configurations not set to UTCTimezone-sensitive assertion.

Remediation:

  • Pin CI to one OS / one timezone (TZ=UTC) for deterministic runs.
  • Run snapshot updates only in CI, never from a developer laptop (per playwright-snapshots).
  • For path-sensitive code, normalize with path.posix.join() / node:path.

Pattern 8: randomness

Tests use random data without a controlled seed.

SignalWhat's happening
Failures don't reproduce on retryTest data was randomized; the failing combination is gone.
Test asserts a property that holds "almost always"Property-based test exposing a real edge case (this is good - fix the production bug).
Faker-generated data triggers a layout overflowRandom string longer than the assertion expected.

Remediation:

  • Seed every random source: Math.random via seedrandom, faker via faker.seed(N), property-based testing via fc.assert(prop, { seed }).
  • For property-based failures, don't mark them as flake - copy the failing seed into a regression test.
  • Persist the seed used in each CI run as a build artifact so a flake can be replayed.

Triage decision tree

Test fails ~50% of runs?
├── Yes → likely "shared parallel state" or "test ordering"
└── No → fails ~5-20% of runs?
    ├── Yes → likely "async/timing" or "network"
    └── No → fails only on specific OS / runner?
        ├── Yes → "environment variance"
        └── No → fails after long suite duration?
            ├── Yes → "resource leaks"
            └── No → fails after unrelated UI change?
                ├── Yes → "locator drift"
                └── No → does the test use random data?
                    ├── Yes → "randomness"
                    └── No → run a structured bisect

For systematic bisection, run a structured bisect that varies one axis at a time per the patterns above.

Code-level fixes

Once the pattern is named - by inspection above or by experiment via flake-axis-bisection - apply the smallest change the pattern calls for (a targeted edit, not a rewrite), then re-measure at a real depth: re-run at an N chosen from the failure rate you are willing to ship, not the screening N; a clean 0/20 does not prove the flake is gone (flake-axis-bisection). Quarantine via flaky-test-quarantine if the flake blocks the trunk while the fix is in review.

The per-pattern code fixes, grounded in Playwright, Cypress, MSW, and Faker official docs:

Worked example

A checkout test, tests/checkout.spec.ts:42, fails about 15% of runs in CI and always passes locally.

  1. Classify. flake-axis-bisection implicates the network-latency axis, and reading the source shows the assertion is gated on a fixed page.waitForTimeout(2000), not on the response. That is Pattern 1 (async / timing): the sleep is shorter than the slowest CI response.
  2. Apply the fix. Replace the fixed sleep with a web-first assertion that retries until the condition holds:
// Before - the 2s sleep races a variable-latency XHR
await page.getByRole('button', { name: 'Place order' }).click();
await page.waitForTimeout(2000);
expect(await page.getByText('Order confirmed').isVisible()).toBe(true);

// After - retries until the confirmation renders or the timeout expires
await page.getByRole('button', { name: 'Place order' }).click();
await expect(page.getByText('Order confirmed')).toBeVisible();
  1. Re-measure and ship. The team's tolerance is 1%, so re-run at N=300 (flake-axis-bisection Step 2). A clean 0/300 bounds the rate at roughly 1%; a clean 0/20 would have proved nothing. No quarantine was needed - the fix landed inside the PR the flake was blocking.

Quick-reference: pattern to fix

PatternKey fixPrimary API
async / timingReplace sleep with auto-wait assertionawait expect(loc).toBeVisible()
test orderingMove setup to beforeEach; roll back DB per testtest.beforeEach / test.afterEach
shared parallel statePer-worker schema / dir / port via workerIndextestInfo.workerIndex
resource leaksbrowser.close() in afterAll with try/finallytest.afterAll + try/finally
networkMock at boundary; never reach real endpointspage.route() / MSW
locator driftRole-based locators; data-testid fallbackgetByRole()
environment variancePin TZ=UTC; freeze clock; normalize pathspage.clock.install()
randomnessSeed every RNG; persist seed in CI logfaker.seed(N)

Per-fix citations live in the three reference files above.

References

  • google-flaky - Google Testing Blog overview.
  • google-causes - Google's correlation analysis on ~4.2M tests; "test size correlates with flakiness rate."
  • flaky-test-quarantine - workflow that uses this catalog during triage.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

Builds a CI gate that fails the build on **new** WCAG / a11y violations introduced by a PR while grandfathering pre-existing violations on a per-rule / per-page baseline. Aggregates verdicts from axe-core / pa11y / Lighthouse a11y / WAVE / IBM Equal Access scans. Use when a project has accumulated a11y debt and a strict "zero violations" gate would block every PR - the ratchet pattern lets the team ship while preventing regressions.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Workflow skill that builds an A/B-test validity checklist from an experiment proposal, walking the canonical design-correctness gates - pre-registered OEC/power/guardrails, randomization unit + SRM check, assignment integrity, telemetry, peeking discipline, novelty/primacy, post-experiment SRM re-check - into a per-experiment checklist + sign-off form. Use when launching, auditing, or governing an experiment. For pitfall mechanics (guardrails, peeking) see experiment-results-interpreter's references; to read an already-valid result use experiment-results-interpreter; for per-SDK harness tests use experiment-sdk-testing - this gates DESIGN, not SDK code.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

The single install-flow skill: the reference contract for the PWA install flow (installability gate fields, `beforeinstallprompt` handshake, per-platform paths - Android WebAPK / iOS Share menu / Firefox no-op - and the `display-mode` post-install signal, in references/install-flow-reference.md) plus the build-an-X workflow that emits the Add-to-Home-Screen suite. Walks the four-stage timeline, emitting one test per gate cell per [web.dev/articles/install-criteria][install-criteria], the deferred-prompt → `prompt()` → `userChoice` chain per [web.dev/articles/customize-install][customize-install], the iOS Safari manual-metadata branch (`apple-touch-icon`) per [web.dev/learn/pwa/installation][learn-pwa], and the post-install `(display-mode: standalone)` MQ assertion. Output: a Playwright spec with per-stage cells plus a coverage matrix. Use when a PWA's manifest, icons, or install handler change, when install conversion drops at an unknown stage, or when triaging a flaky install assertion.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Build-an-X workflow that uses an LLM to map existing tests to spec sections - given a spec doc + the test suite, the LLM identifies which tests cover which sections, surfaces uncovered sections (gap), and recommends specific tests to add. Output is a coverage matrix per spec ID. Scope is mapping tests that already exist and naming the gaps, not authoring tests for new acceptance criteria. Use when a spec doc and a test suite both exist but nobody can say which requirements are actually covered - before a release sign-off, an audit, or a decision about where to spend the next round of test effort.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Generates tests from natural-language specs (acceptance criteria, user stories, requirements) using an LLM, with confidence scoring per test case (LLM self-assessment plus heuristics: assertion quality, naming, completeness), batching uncertain cases for human review, and integration with the team's existing test framework. Use when the user asks to generate unit tests from acceptance criteria, convert user stories to test cases, automate test creation from requirements, or augment a spec-driven test suite with AI-generated stubs that are then curated before merge.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Configures Allure Report (test-runner adapter install, `allure-results` directory wiring, `categories.json` for failure classification, `history-trend.json` retention via the copy-history-between-runs pattern), runs the Allure CLI to convert `allure-results` to a static HTML site, and uploads the report as a CI artifact. Use when the team needs richer test reporting than JUnit XML - step-level attachments, per-test history, retry tracking, and severity / epic / feature labeling across framework-agnostic adapters (pytest, Jest, JUnit, TestNG, NUnit, Mocha). As a rich static HTML report generator, it is the open-source alternative to the sunset ExtentReports (JVM/.NET per-test HTML narrative); for hosted cross-run flakiness analytics rather than a static per-run report use currents-integration.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

testland のスキルをすべて見る

このスキルの問題を報告する