Invoke whenever writing, changing, reviewing, or sweeping tests. Authoring gate for new tests, plus an audit workflow for low-value, implementation-coupled, or
复制下面这句话,粘贴给 Claude Code、Codex、Cursor 等 AI 编程工具,它会读取安装说明并在你确认后完成安装。
请阅读 https://ai.atlankj.com/install/asset/gh-test-audit-bd2216000b6c ,按照其中的说明把「test-audit」安装到你(当前 AI 工具)中。执行前先告诉我将运行的命令和写入的位置,等我确认。
查看 AI 将读取的安装说明正在读取 GitHub 原文…
内容来自 GitHub 原始文件,由原作者维护。在 GitHub 查看
Three modes, one value bar. Authoring gates every new or changed test at write time. Audit runs a focused sweep of existing tests that re-assert source, duplicate stronger proof, couple to implementation, or keep test-only production seams alive. Campaign prunes one subsystem's whole test surface in parallel lanes. Optimize for confidence, not deletion count — but a test that cannot name the bug it catches is cost, not coverage.
Read .claude/rules/sim-testing.md first: it defines the test layers, file naming, and the
mechanics (global mocks, @sim/testing, performance rules).
*.integration.ts), a running app over real HTTP, or the packaged desktop app
(Playwright). Every E2E run ends with a verifiable, repeatable artifact: a JSON report of
checks with pass/fail and durations, an HTTP status log, a trace, or a screenshot, written to a
path the caller controls (<SUITE>_REPORT_PATH) and uploaded by CI on failure.
apps/sim/scripts/test-scim-e2e.ts is the reference shape.Before adding any test, answer all four. A missing answer means do not add it.
next build,
bun run check:audits, and the integration/E2E suites are coverage too. Each contract has one
primary owner at the strongest boundary; another layer needs its own distinct risk. Prefer
extending an existing table-driven case over a near-duplicate test.Then check it against every junk pattern below. A match fails the gate unless the retention bar names the contract it independently guards. A test that would break under behavior-preserving refactoring asserts implementation, not behavior.
Regression tests must fail on the pre-fix code for the intended reason. Revert each guard of the fix separately and watch the test named for that guard go red, then restore. A regression test that never demonstrably failed proves the mock, not the fix. One regression at the owner boundary covers the bug; do not replay it at every layer it crosses.
toBeDefined()-only tests; "renders without crashing";check:audits own these;toHaveBeenCalledWith on the mocks,
or re-assert a mock's canned return;readFileSync(src) + toContain);vi.mock factory for a module vitest.setup.ts or @sim/testing already mocks, or a
local copy of a @sim/testing helper (bun run check:test-patterns fails on these).Keep a test when it independently enforces one of:
Also keep call ordering when order is observable, and a source inspection when it is the cheapest independent guard of a user-facing byte, key, or path. A retained test that fails on the baseline is a possible product bug: reproduce it and fix the owner rather than deleting it. Static or slow is not a deletion reason.
Keep discovery read-only and report evidence before editing. Before judging a candidate, read the
complete test and its production owner, callers, sibling implementations, overlapping tests, CI
routing (CI discovers *.integration.ts by glob; .github/workflows/*.yml names a few scripts and
files by path), and relevant history
(git log --format='%h %s' -5 -- <file>).
Record for every deletion candidate: the test and location; the failure it can actually detect; non-test callers of the seam it covers; the stronger remaining proof (or why none is needed); the production or test-support code its deletion unlocks; and the focused validation command.
Edit shape. One coherent owner-boundary batch per PR. When pruning inside a file, also delete
now-unused imports, mocks, fixtures, and helpers. Delete test-only exports and dead production
paths instead of preserving aliases (rg -n '<name>' --glob '!**/*.test.*' must show no other
reference, including string and dynamic-import references; never delete route files, registry
entries, or generated files). Prefer net-negative production LOC. Do not add replacement tests
that restate the same implementation.
For a whole subsystem or the whole repo:
*.integration.ts, *.live.test.ts, __integration__/**, apps/desktop/e2e/**,
and every path named in .github/workflows/*.yml).git worktree add -b <branch> <path> <base>,
then bun install --frozen-lockfile inside it). Lanes never share a checkout, never symlink
node_modules, and never use git stash — the stash is shared across worktrees.packages/testing/**, fixtures,
helpers) that no remaining test imports.Never edit source or tests while Vitest is running in the same checkout.
.claude/rules/sim-testing.md → Running).bun run type-check in that workspace.bun run check:audits from the repo root (some audits list test files by path).bun run lint, then git diff --check.git diff --shortstat with production and test changes counted separately.Report the categories removed, production simplifications, retained false positives and why they stay, the validation actually run, production vs test LOC, and named follow-ups.