[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71AYVHKX89YAFQA2Y7S4ZRP":3,"skill-same:01M71AYVHKX89YAFQA2Y7S4ZRP":136},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":67,"commitSha":68,"skillDirectory":69,"forksCount":70,"repositoryHtmlUrl":71,"repositoryHomepageUrl":72,"ownerHtmlUrl":73,"ownerBlogUrl":74,"ownerDescription":75,"updatedAt":76,"install":77,"resources":90},"01M71AYVHKX89YAFQA2Y7S4ZRP","test-coverage",null,"Finds complex business logic, edge cases, corner cases, and past regressions\nthat lack tests, then writes the missing unit tests (and integration\u002FE2E\ntests when the risk genuinely crosses a boundary) — enforcing Google's\nTesting on the Toilet best practices (real > fake > mock, don't mock types\nyou don't own, verify state not queries, avoid change-detector tests, DAMP\nover DRY in tests, limit mocks per test). Use when asked to \"add tests\",\n\"cover edge cases\", \"check test coverage\", \"write missing tests\", \"harden\nthe tests\", \"test this properly\", or \"make sure this is tested\".","ariadoss\u002Fsuperskills","ariadoss","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F414341?v=4","01M71AC7383PT6JCRZSQJ4AVTM","Danilo Stern-Sapad","01M71AC73Y7NTBTJ9KQYNENRRE",12,"MIT","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"test coverage","test","coverage","paths","edit","write","read","past","e2e tests","change","sure","dry","Bash","you","when","toilet","testing","scope","types","unit","2026-11-10 10:12:30",false,"---\nname: test-coverage\nversion: 1.0.0\ndescription: |\n  Finds complex business logic, edge cases, corner cases, and past regressions\n  that lack tests, then writes the missing unit tests (and integration\u002FE2E\n  tests when the risk genuinely crosses a boundary) — enforcing Google's\n  Testing on the Toilet best practices (real > fake > mock, don't mock types\n  you don't own, verify state not queries, avoid change-detector tests, DAMP\n  over DRY in tests, limit mocks per test). Use when asked to \"add tests\",\n  \"cover edge cases\", \"check test coverage\", \"write missing tests\", \"harden\n  the tests\", \"test this properly\", or \"make sure this is tested\".\ntriggers:\n  - add tests\n  - cover edge cases\n  - check test coverage\n  - write missing tests\n  - harden the tests\n  - test this properly\n  - make sure this is tested\nargument-hint: '\u003Coptional: paths\u002Fglobs to scope, or --full for the whole repo>'\nallowed-tools:\n  - Bash\n  - Read\n  - Edit\n  - Write\n  - Grep\n  - Glob\n  - Task\n---\n\n# \u002Ftest-coverage\n\nFinds where complex business logic, edge cases, corner cases, and past\nregressions are undertested, then **writes and applies** the missing tests.\n`\u002Fqa-full` Step 9 runs this skill as the fix phase of its coverage check, then\nre-runs the suite to verify.\n\n## Hard rules\n\n- **The bar is `ENGINEERING_STANDARDS.md`'s TDD section** (referenced, not\n  restated): every new public function, branch, and error path needs a test;\n  ≥90% lines on new\u002Fchanged modules is the default target; a test that can't\n  run in the project's real runner doesn't count.\n- **A failing test against existing code is a finding, not noise.** If a test\n  you write to cover a \"should never happen\" case actually fails, you found a\n  real bug or an already-broken regression — report it with repro evidence and\n  do **not** rewrite the test to match the broken behavior. Fix the test's\n  scope only when the *spec* was wrong, never to paper over a real defect\n  without telling the user.\n- **Every test you write or touch follows the Google practices in Step 5** —\n  this is not optional flavor text, it's the acceptance bar for the tests this\n  skill produces.\n- **Smallest correct test level.** Default to unit. Escalate to integration or\n  E2E only per the pyramid rule in Step 4 — don't reach for Playwright to\n  cover a pure function.\n- **Ground every gap in evidence**: file:line of the untested logic, the\n  specific input class missing coverage, and (for regressions) the commit that\n  introduced the bug.\n\n## Step 1: Scope\n\n1. If `$ARGUMENTS` gives paths\u002Fglobs, scope to those. If it says `--full`,\n   scope to the whole repo. Otherwise default to the current branch's diff:\n   `git diff --name-only \u003Cbase>...HEAD` plus `git status --porcelain`\n   (same base-branch detection as `\u002Fqa-full` Step 1).\n2. Detect the test framework and runner from the project (`package.json`\n   scripts, `pytest.ini`\u002F`pyproject.toml`, `go test`, `bats`, `*.csproj`,\n   `Gemfile`). If ambiguous, ask rather than guess — writing tests against the\n   wrong runner is worse than asking one question.\n3. Record scope, runner, and command at the top of your working notes.\n\nIf the scope is empty, say so and stop — there's nothing to cover.\n\n## Step 2: Find undertested complex logic\n\nFor each in-scope file, flag functions\u002Fmethods that are \"complex\" by any of:\n\n- **Multiple branches** — 2+ `if`\u002F`switch`\u002Fternary paths, especially ones that\n  return different values or take different side-effecting actions.\n- **Loops with accumulation or early exit** — aggregation, search, dedup,\n  pagination.\n- **State machines \u002F status transitions** — anything with an enum of states\n  and rules about which transitions are legal.\n- **Calculations with domain rules** — money\u002Fcurrency, dates\u002Ftimezones,\n  permissions\u002Fauthorization, rate limiting, parsing\u002Fserialization, validation.\n- **Recursive functions.**\n- **Anything already flagged by `\u002Fdb-optimize`, `\u002Fperf-profile`, or a prior\n  `\u002Fcode-review` as high-risk** — risk-driven prioritization: spend the\n  budget here first, not on trivial getters.\n\nFor each, grep the test tree for a reference to that function\u002Fclass name. No\nreference (or only a shallow \"doesn't throw\" smoke test) ⇒ gap.\n\n## Step 3: Enumerate edge and corner cases per gap\n\nFor each gap from Step 2, work out the input-partition classes relevant to\n*that* logic — don't apply a rote checklist blindly, reason about what this\nfunction actually branches on. Common classes to check against:\n\n- null \u002F undefined \u002F missing-key vs. present-but-empty (`\"\"`, `[]`, `{}`, `0`)\n- boundary values: zero, negative, max\u002Fmin of the type, off-by-one at a\n  loop\u002Farray edge\n- single-element and duplicate-element collections\n- malformed \u002F unexpected-shape input (extra fields, wrong type, truncated)\n- concurrent or repeated calls (double-submit, idempotency)\n- unicode\u002Fencoding edge cases in string handling\n- timezone\u002FDST boundaries and leap years in date logic\n- floating-point precision in money\u002Fpercentage math\n- combinations of two+ conditions that individually pass but together hit an\n  unhandled branch (the actual \"corner\" case, not just one axis at a time)\n\nOnly list classes that are **reachable** through the function's real callers —\ndon't invent tests for input shapes the type system or a validator already\nrules out upstream.\n\n## Step 4: Regression coverage\n\n1. `git log` the in-scope files for commits whose message matches\n   `fix|bug|regression|hotfix|revert` (case-insensitive).\n2. For each match, check whether that commit (or a nearby one) added or\n   modified a test. No test touched ⇒ **regression gap**: the bug could\n   reappear silently.\n3. For each regression gap, write a test that reproduces the *original*\n   failure mode (read the pre-fix diff to know what broke) and pins the fixed\n   behavior — the classic \"this test would have caught it\" test.\n\n## Step 5: Decide the test level — pyramid, not instinct\n\n- **Unit (default).** The logic's correctness can be verified with real\n  objects\u002Fpure functions and no I\u002FO. This is nearly everything from Steps 2–4.\n- **Integration.** Escalate only when the *real risk* lives at a boundary a\n  unit test would fake away — an actual SQL query's behavior, a real\n  filesystem\u002Fqueue interaction, a multi-module contract. Prefer a real\n  dependency or an in-process fake\u002Fhermetic server over mocking the boundary\n  (see [`rules\u002Freal-fake-mock-hierarchy.md`](rules\u002Freal-fake-mock-hierarchy.md));\n  reach for a mock only when no hermetic option exists.\n- **E2E.** Reserve for a small number of critical golden-path user journeys\n  where the risk is the *wiring between* already-unit-tested pieces, not any\n  single piece's logic. Use `\u002Fplaywright` for browser E2E — don't hand-roll a\n  driver here.\n- State which level you chose per gap and why in one line — this is the\n  artifact a reviewer checks when they ask \"why is this an integration test.\"\n\n## Step 6: Google testing best practices (apply to every test you write)\n\nThese are Google's Testing on the Toilet rules that close real gaps in most\ntest suites. Each is a short standalone file under `rules\u002F` — a rule plus a\nconcrete good\u002Fbad example — so you pull in the detail only for the rule that's\nactually in play, instead of re-reading all eleven every run. Skim the\none-liners below; open a file when its situation applies to the test you're\nabout to write. When you're already touching an existing test for a nearby\nreason, fix violations you see rather than adding a `TODO`.\n\n| Rule | Applies when |\n|---|---|\n| [`real-fake-mock-hierarchy.md`](rules\u002Freal-fake-mock-hierarchy.md) | About to reach for a mock — check real\u002Ffake first |\n| [`dont-mock-types-you-dont-own.md`](rules\u002Fdont-mock-types-you-dont-own.md) | The dependency is a third-party type, not your own |\n| [`verify-state-changes-only.md`](rules\u002Fverify-state-changes-only.md) | About to `verify()`\u002Fassert-called-with on any call |\n| [`state-over-interaction-testing.md`](rules\u002Fstate-over-interaction-testing.md) | Choosing what the assertion should check |\n| [`avoid-change-detector-tests.md`](rules\u002Favoid-change-detector-tests.md) | The test's structure is starting to mirror the code's branches |\n| [`know-your-test-doubles.md`](rules\u002Fknow-your-test-doubles.md) | Picking which kind of double to use |\n| [`limit-mocks-per-test.md`](rules\u002Flimit-mocks-per-test.md) | The test already has 2+ mocks |\n| [`damp-not-dry.md`](rules\u002Fdamp-not-dry.md) | Tempted to extract a shared fixture\u002Fsetup helper |\n| [`test-behaviors-not-methods.md`](rules\u002Ftest-behaviors-not-methods.md) | Naming a test or deciding how many tests one function needs |\n| [`inject-dont-hardcode-statics.md`](rules\u002Finject-dont-hardcode-statics.md) | The gap traces back to a singleton\u002Fstatic\u002F`Date.now()` |\n| [`descriptive-names-clean-data.md`](rules\u002Fdescriptive-names-clean-data.md) | Naming a test or building its fixture data |\n\n## Step 7: Write the tests\n\nFor each confirmed gap (Steps 2–4), at the chosen level (Step 5), following\nthe Step 6 `rules\u002F` checklist:\n\n1. Write the test. Run it. If it's testing genuinely new behavior it should\n   fail first (red) against a stubbed-out expectation, or pass immediately\n   because the behavior already exists and you're only closing a coverage\n   gap — either is fine, but **run it and read the actual result**, don't\n   assume.\n2. If a new test fails against unmodified production code, stop and report it\n   as a bug\u002Fregression finding (see Hard rules) instead of silently adjusting\n   the assertion.\n3. Apply the test file changes (this skill writes and commits to the working\n   tree).\n\n## Step 8: Run the full suite and report\n\nRun the project's real test command. Then report:\n\n```markdown\n# Test coverage — \u003Cscope> @ \u003Cdate>\n\nRunner: \u003Ccommand>   Files scoped: N   New tests added: M\n\n## Gaps closed\n- \u003Cfile:line> \u003Cfunction> — \u003Cinput class(es) covered> — \u003Cunit|integration|e2e> — \u003Ctest file:line>\n\n## Regressions pinned\n- \u003Coriginal bug commit> — \u003Cfile:line> — reproduces: \u003Cwhat broke> — \u003Ctest file:line>\n\n## Bugs found while writing tests (not fixed here)\n- \u003Cfile:line> — \u003Ctest that exposes it> — \u003Cwhy it's a real defect, not a bad test>\n\n## Best-practice fixes applied to existing tests touched\n- \u003Cfile:line> — \u003Cwhich rules\u002F file> — \u003Cwhat changed>\n\n## Suite result\n\u003Cpass\u002Ffail summary from the real run>\n```\n\n## Anti-patterns (do not do)\n\n- Writing a mock for a dependency you own instead of just using the real\n  thing or a fake (`rules\u002Freal-fake-mock-hierarchy.md`).\n- Mocking a third-party type directly instead of wrapping it\n  (`rules\u002Fdont-mock-types-you-dont-own.md`).\n- `verify()` on a getter\u002Fquery call (`rules\u002Fverify-state-changes-only.md`).\n- A test that re-implements the production branching logic to compute its\n  expected value — that's not a test, it's a mirror\n  (`rules\u002Favoid-change-detector-tests.md`).\n- Reaching for Playwright\u002FE2E to cover a pure function that a unit test\n  covers in milliseconds (Step 5).\n- \"Fixing\" a failing test by loosening its assertion to match a real bug,\n  without telling the user (Hard rules).\n- Padding the report with trivial getter\u002Fsetter coverage while a genuinely\n  complex branch stays untested — risk-driven prioritization (Step 2).\n\n## Related commands\n\n- `\u002Ftdd` — the write-code-first-with-a-failing-test loop *while implementing\n  new code*. `\u002Ftest-coverage` runs *after* code exists, to close gaps in what\n  already landed.\n- `\u002Fqa-full` Step 9 — the coverage check in the pre-ship pipeline; it audits\n  for gaps, runs `\u002Ftest-coverage` to close them, then re-runs the suite. New\n  public surface still untested afterwards is a ship blocker.\n- `\u002Fplaywright` — the E2E harness this skill hands off to when Step 5 decides\n  a gap needs browser-level coverage.\n- `\u002Fcode-review` — correctness review of the diff; `\u002Ftest-coverage` is the\n  complementary \"does the diff have adequate tests\" pass, and can be run right\n  after a `\u002Fcode-review` pass identifies risky logic.\n- `\u002Fdebug` — when Step 7 surfaces a real bug via a new test, use `\u002Fdebug` to\n  root-cause and fix it (this skill reports the bug, it doesn't fix production\n  code).\n","# \u002Ftest-coverage\n\nFinds where complex business logic, edge cases, corner cases, and past\nregressions are undertested, then **writes and applies** the missing tests.\n`\u002Fqa-full` Step 9 runs this skill as the fix phase of its coverage check, then\nre-runs the suite to verify.\n\n## Hard rules\n\n- **The bar is `ENGINEERING_STANDARDS.md`'s TDD section** (referenced, not\n  restated): every new public function, branch, and error path needs a test;\n  ≥90% lines on new\u002Fchanged modules is the default target; a test that can't\n  run in the project's real runner doesn't count.\n- **A failing test against existing code is a finding, not noise.** If a test\n  you write to cover a \"should never happen\" case actually fails, you found a\n  real bug or an already-broken regression — report it with repro evidence and\n  do **not** rewrite the test to match the broken behavior. Fix the test's\n  scope only when the *spec* was wrong, never to paper over a real defect\n  without telling the user.\n- **Every test you write or touch follows the Google practices in Step 5** —\n  this is not optional flavor text, it's the acceptance bar for the tests this\n  skill produces.\n- **Smallest correct test level.** Default to unit. Escalate to integration or\n  E2E only per the pyramid rule in Step 4 — don't reach for Playwright to\n  cover a pure function.\n- **Ground every gap in evidence**: file:line of the untested logic, the\n  specific input class missing coverage, and (for regressions) the commit that\n  introduced the bug.\n\n## Step 1: Scope\n\n1. If `$ARGUMENTS` gives paths\u002Fglobs, scope to those. If it says `--full`,\n   scope to the whole repo. Otherwise default to the current branch's diff:\n   `git diff --name-only \u003Cbase>...HEAD` plus `git status --porcelain`\n   (same base-branch detection as `\u002Fqa-full` Step 1).\n2. Detect the test framework and runner from the project (`package.json`\n   scripts, `pytest.ini`\u002F`pyproject.toml`, `go test`, `bats`, `*.csproj`,\n   `Gemfile`). If ambiguous, ask rather than guess — writing tests against the\n   wrong runner is worse than asking one question.\n3. Record scope, runner, and command at the top of your working notes.\n\nIf the scope is empty, say so and stop — there's nothing to cover.\n\n## Step 2: Find undertested complex logic\n\nFor each in-scope file, flag functions\u002Fmethods that are \"complex\" by any of:\n\n- **Multiple branches** — 2+ `if`\u002F`switch`\u002Fternary paths, especially ones that\n  return different values or take different side-effecting actions.\n- **Loops with accumulation or early exit** — aggregation, search, dedup,\n  pagination.\n- **State machines \u002F status transitions** — anything with an enum of states\n  and rules about which transitions are legal.\n- **Calculations with domain rules** — money\u002Fcurrency, dates\u002Ftimezones,\n  permissions\u002Fauthorization, rate limiting, parsing\u002Fserialization, validation.\n- **Recursive functions.**\n- **Anything already flagged by `\u002Fdb-optimize`, `\u002Fperf-profile`, or a prior\n  `\u002Fcode-review` as high-risk** — risk-driven prioritization: spend the\n  budget here first, not on trivial getters.\n\nFor each, grep the test tree for a reference to that function\u002Fclass name. No\nreference (or only a shallow \"doesn't throw\" smoke test) ⇒ gap.\n\n## Step 3: Enumerate edge and corner cases per gap\n\nFor each gap from Step 2, work out the input-partition classes relevant to\n*that* logic — don't apply a rote checklist blindly, reason about what this\nfunction actually branches on. Common classes to check against:\n\n- null \u002F undefined \u002F missing-key vs. present-but-empty (`\"\"`, `[]`, `{}`, `0`)\n- boundary values: zero, negative, max\u002Fmin of the type, off-by-one at a\n  loop\u002Farray edge\n- single-element and duplicate-element collections\n- malformed \u002F unexpected-shape input (extra fields, wrong type, truncated)\n- concurrent or repeated calls (double-submit, idempotency)\n- unicode\u002Fencoding edge cases in string handling\n- timezone\u002FDST boundaries and leap years in date logic\n- floating-point precision in money\u002Fpercentage math\n- combinations of two+ conditions that individually pass but together hit an\n  unhandled branch (the actual \"corner\" case, not just one axis at a time)\n\nOnly list classes that are **reachable** through the function's real callers —\ndon't invent tests for input shapes the type system or a validator already\nrules out upstream.\n\n## Step 4: Regression coverage\n\n1. `git log` the in-scope files for commits whose message matches\n   `fix|bug|regression|hotfix|revert` (case-insensitive).\n2. For each match, check whether that commit (or a nearby one) added or\n   modified a test. No test touched ⇒ **regression gap**: the bug could\n   reappear silently.\n3. For each regression gap, write a test that reproduces the *original*\n   failure mode (read the pre-fix diff to know what broke) and pins the fixed\n   behavior — the classic \"this test would have caught it\" test.\n\n## Step 5: Decide the test level — pyramid, not instinct\n\n- **Unit (default).** The logic's correctness can be verified with real\n  objects\u002Fpure functions and no I\u002FO. This is nearly everything from Steps 2–4.\n- **Integration.** Escalate only when the *real risk* lives at a boundary a\n  unit test would fake away — an actual SQL query's behavior, a real\n  filesystem\u002Fqueue interaction, a multi-module contract. Prefer a real\n  dependency or an in-process fake\u002Fhermetic server over mocking the boundary\n  (see [`rules\u002Freal-fake-mock-hierarchy.md`](rules\u002Freal-fake-mock-hierarchy.md));\n  reach for a mock only when no hermetic option exists.\n- **E2E.** Reserve for a small number of critical golden-path user journeys\n  where the risk is the *wiring between* already-unit-tested pieces, not any\n  single piece's logic. Use `\u002Fplaywright` for browser E2E — don't hand-roll a\n  driver here.\n- State which level you chose per gap and why in one line — this is the\n  artifact a reviewer checks when they ask \"why is this an integration test.\"\n\n## Step 6: Google testing best practices (apply to every test you write)\n\nThese are Google's Testing on the Toilet rules that close real gaps in most\ntest suites. Each is a short standalone file under `rules\u002F` — a rule plus a\nconcrete good\u002Fbad example — so you pull in the detail only for the rule that's\nactually in play, instead of re-reading all eleven every run. Skim the\none-liners below; open a file when its situation applies to the test you're\nabout to write. When you're already touching an existing test for a nearby\nreason, fix violations you see rather than adding a `TODO`.\n\n| Rule | Applies when |\n|---|---|\n| [`real-fake-mock-hierarchy.md`](rules\u002Freal-fake-mock-hierarchy.md) | About to reach for a mock — check real\u002Ffake first |\n| [`dont-mock-types-you-dont-own.md`](rules\u002Fdont-mock-types-you-dont-own.md) | The dependency is a third-party type, not your own |\n| [`verify-state-changes-only.md`](rules\u002Fverify-state-changes-only.md) | About to `verify()`\u002Fassert-called-with on any call |\n| [`state-over-interaction-testing.md`](rules\u002Fstate-over-interaction-testing.md) | Choosing what the assertion should check |\n| [`avoid-change-detector-tests.md`](rules\u002Favoid-change-detector-tests.md) | The test's structure is starting to mirror the code's branches |\n| [`know-your-test-doubles.md`](rules\u002Fknow-your-test-doubles.md) | Picking which kind of double to use |\n| [`limit-mocks-per-test.md`](rules\u002Flimit-mocks-per-test.md) | The test already has 2+ mocks |\n| [`damp-not-dry.md`](rules\u002Fdamp-not-dry.md) | Tempted to extract a shared fixture\u002Fsetup helper |\n| [`test-behaviors-not-methods.md`](rules\u002Ftest-behaviors-not-methods.md) | Naming a test or deciding how many tests one function needs |\n| [`inject-dont-hardcode-statics.md`](rules\u002Finject-dont-hardcode-statics.md) | The gap traces back to a singleton\u002Fstatic\u002F`Date.now()` |\n| [`descriptive-names-clean-data.md`](rules\u002Fdescriptive-names-clean-data.md) | Naming a test or building its fixture data |\n\n## Step 7: Write the tests\n\nFor each confirmed gap (Steps 2–4), at the chosen level (Step 5), following\nthe Step 6 `rules\u002F` checklist:\n\n1. Write the test. Run it. If it's testing genuinely new behavior it should\n   fail first (red) against a stubbed-out expectation, or pass immediately\n   because the behavior already exists and you're only closing a coverage\n   gap — either is fine, but **run it and read the actual result**, don't\n   assume.\n2. If a new test fails against unmodified production code, stop and report it\n   as a bug\u002Fregression finding (see Hard rules) instead of silently adjusting\n   the assertion.\n3. Apply the test file changes (this skill writes and commits to the working\n   tree).\n\n## Step 8: Run the full suite and report\n\nRun the project's real test command. Then report:\n\n```markdown\n# Test coverage — \u003Cscope> @ \u003Cdate>\n\nRunner: \u003Ccommand>   Files scoped: N   New tests added: M\n\n## Gaps closed\n- \u003Cfile:line> \u003Cfunction> — \u003Cinput class(es) covered> — \u003Cunit|integration|e2e> — \u003Ctest file:line>\n\n## Regressions pinned\n- \u003Coriginal bug commit> — \u003Cfile:line> — reproduces: \u003Cwhat broke> — \u003Ctest file:line>\n\n## Bugs found while writing tests (not fixed here)\n- \u003Cfile:line> — \u003Ctest that exposes it> — \u003Cwhy it's a real defect, not a bad test>\n\n## Best-practice fixes applied to existing tests touched\n- \u003Cfile:line> — \u003Cwhich rules\u002F file> — \u003Cwhat changed>\n\n## Suite result\n\u003Cpass\u002Ffail summary from the real run>\n```\n\n## Anti-patterns (do not do)\n\n- Writing a mock for a dependency you own instead of just using the real\n  thing or a fake (`rules\u002Freal-fake-mock-hierarchy.md`).\n- Mocking a third-party type directly instead of wrapping it\n  (`rules\u002Fdont-mock-types-you-dont-own.md`).\n- `verify()` on a getter\u002Fquery call (`rules\u002Fverify-state-changes-only.md`).\n- A test that re-implements the production branching logic to compute its\n  expected value — that's not a test, it's a mirror\n  (`rules\u002Favoid-change-detector-tests.md`).\n- Reaching for Playwright\u002FE2E to cover a pure function that a unit test\n  covers in milliseconds (Step 5).\n- \"Fixing\" a failing test by loosening its assertion to match a real bug,\n  without telling the user (Hard rules).\n- Padding the report with trivial getter\u002Fsetter coverage while a genuinely\n  complex branch stays untested — risk-driven prioritization (Step 2).\n\n## Related commands\n\n- `\u002Ftdd` — the write-code-first-with-a-failing-test loop *while implementing\n  new code*. `\u002Ftest-coverage` runs *after* code exists, to close gaps in what\n  already landed.\n- `\u002Fqa-full` Step 9 — the coverage check in the pre-ship pipeline; it audits\n  for gaps, runs `\u002Ftest-coverage` to close them, then re-runs the suite. New\n  public surface still untested afterwards is a ship blocker.\n- `\u002Fplaywright` — the E2E harness this skill hands off to when Step 5 decides\n  a gap needs browser-level coverage.\n- `\u002Fcode-review` — correctness review of the diff; `\u002Ftest-coverage` is the\n  complementary \"does the diff have adequate tests\" pass, and can be run right\n  after a `\u002Fcode-review` pass identifies risky logic.\n- `\u002Fdebug` — when Step 7 surfaces a real bug via a new test, use `\u002Fdebug` to\n  root-cause and fix it (this skill reports the bug, it doesn't fix production\n  code).\n",{"name":5,"version":49,"triggers":50,"description":58,"allowed-tools":59,"argument-hint":66},"1.0.0",[51,52,53,54,55,56,57],"add tests","cover edge cases","check test coverage","write missing tests","harden the tests","test this properly","make sure this is tested","Finds complex business logic, edge cases, corner cases, and past regressions\nthat lack tests, then writes the missing unit tests (and integration\u002FE2E\ntests when the risk genuinely crosses a boundary) — enforcing Google's\nTesting on the Toilet best practices (real > fake > mock, don't mock types\nyou don't own, verify state not queries, avoid change-detector tests, DAMP\nover DRY in tests, limit mocks per test). Use when asked to \"add tests\",\n\"cover edge cases\", \"check test coverage\", \"write missing tests\", \"harden\nthe tests\", \"test this properly\", or \"make sure this is tested\".\n",[36,60,61,62,63,64,65],"Read","Edit","Write","Grep","Glob","Task","\u003Coptional: paths\u002Fglobs to scope, or --full for the whole repo>","main","c7ec8d78e5dc37484c2cfe90ab04de163d97dd41","skills\u002Ftest-coverage",0,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills","https:\u002F\u002Fhyperion360.com\u002Fblog\u002Fparallel-ai-agents-engineering-workflow\u002F","https:\u002F\u002Fgithub.com\u002Fariadoss","https:\u002F\u002Fdanilosapad.com\u002F","CEO & Founder of @Hyperion360","2026-11-13 04:11:07",{"source":8,"skillName":5,"commands":78,"prompt":88,"zipAvailable":89},[79,82,85],{"tool":80,"command":81},"npx","npx skills add ariadoss\u002Fsuperskills --skill test-coverage",{"tool":83,"command":84},"bunx","bunx skills add ariadoss\u002Fsuperskills --skill test-coverage",{"tool":86,"command":87},"pnpm","pnpm dlx skills add ariadoss\u002Fsuperskills --skill test-coverage","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002FSKILL.md",true,[91,97,101,105,108,112,116,120,124,128,132],{"path":92,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":95,"sourceHtmlUrl":96},"rules\u002Favoid-change-detector-tests.md","REFERENCE","参考文档",1131,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Favoid-change-detector-tests.md",{"path":98,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":99,"sourceHtmlUrl":100},"rules\u002Fdamp-not-dry.md",1053,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Fdamp-not-dry.md",{"path":102,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":103,"sourceHtmlUrl":104},"rules\u002Fdescriptive-names-clean-data.md",941,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Fdescriptive-names-clean-data.md",{"path":106,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":99,"sourceHtmlUrl":107},"rules\u002Fdont-mock-types-you-dont-own.md","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Fdont-mock-types-you-dont-own.md",{"path":109,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":110,"sourceHtmlUrl":111},"rules\u002Finject-dont-hardcode-statics.md",1064,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Finject-dont-hardcode-statics.md",{"path":113,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":114,"sourceHtmlUrl":115},"rules\u002Fknow-your-test-doubles.md",996,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Fknow-your-test-doubles.md",{"path":117,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":118,"sourceHtmlUrl":119},"rules\u002Flimit-mocks-per-test.md",1039,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Flimit-mocks-per-test.md",{"path":121,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":122,"sourceHtmlUrl":123},"rules\u002Freal-fake-mock-hierarchy.md",1206,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Freal-fake-mock-hierarchy.md",{"path":125,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":126,"sourceHtmlUrl":127},"rules\u002Fstate-over-interaction-testing.md",804,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Fstate-over-interaction-testing.md",{"path":129,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":130,"sourceHtmlUrl":131},"rules\u002Ftest-behaviors-not-methods.md",955,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Ftest-behaviors-not-methods.md",{"path":133,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":134,"sourceHtmlUrl":135},"rules\u002Fverify-state-changes-only.md",943,"https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-coverage\u002Frules\u002Fverify-state-changes-only.md",[137,160,182,201,230,246],{"skillNo":138,"name":139,"nameZh":6,"description":140,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":141,"categories":142,"keywords":146,"publishedAt":44},"01M71AZE3MPF891RM354EMRYA1","youtube","Download YouTube video transcripts when user provides a YouTube URL or asks to download\u002Fget\u002Ffetch a transcript from YouTube. Also use when user wants to transcribe or get captions\u002Fsubtitles from a YouTube video.","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube\u002FSKILL.md",[143],{"categoryNo":144,"categoryName":145,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",[139,147,148,149,29,150,151,36,152,38,153,154,155,156,30,157,158,159],"user","download","transcribe","transcript","video transcripts","URL","Captions","get","fetch","Video","use","subtitles","transcripts",{"skillNo":161,"name":162,"nameZh":6,"description":163,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":164,"categories":165,"keywords":166,"publishedAt":44},"01M71AZAYR85PW6BJGSQXS4BN2","write-plan","Use when you have a spec or requirements for a multi-step task, before touching code. Produces an engineering plan complete with TDD tasks, DRY\u002FSOLID\u002FYAGNI principles, a required Test Plan & Verification section, and a coverage target — then auto-runs \u002Fplan-eng-review as an independent double-check before execution.","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fwrite-plan\u002FSKILL.md",[],[167,168,29,35,169,170,171,172,37,38,173,174,26,175,176,177,178,179,180,181],"write plan","plan","verification","review","tasks","code","auto","eng","complete","section","for","test plan","target","as","yagni",{"skillNo":183,"name":184,"nameZh":6,"description":185,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":186,"categories":187,"keywords":188,"publishedAt":44},"01M71AZ8NDDP5ZMGEE6FSC4FKR","worktrees","Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fworktrees\u002FSKILL.md",[],[184,189,190,191,157,192,193,194,195,196,197,169,198,38,199,200],"implementation","workspace","with","plans","feature","isolation","git","directory","work","git worktrees","selection","Safety",{"skillNo":202,"name":203,"nameZh":6,"description":204,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":205,"categories":206,"keywords":210,"publishedAt":44},"01M71AZ4ZQHTNWFRZVYHKQFP08","web-perf","Analyzes web performance using Chrome DevTools MCP. Measures Core Web Vitals (LCP, INP, CLS) and supplementary metrics (FCP, TBT, Speed Index), identifies render-blocking resources, network dependency chains, layout shifts, caching issues, and accessibility gaps. Use when asked to audit, profile, debug, or optimize page load performance, Lighthouse scores, or site speed. Biases towards retrieval from current documentation over pre-trained knowledge.","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fweb-perf\u002FSKILL.md",[207],{"categoryNo":208,"categoryName":209,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[211,212,213,214,215,216,217,218,219,38,220,221,222,223,224,225,226,227,228,229],"web","perf","web perf","resources","MCP","layout","optimize","documentation","caching","qa","knowledge","devtools","issues","render","re","performance","chrome devtools","vitals","never",{"skillNo":231,"name":232,"nameZh":6,"description":233,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":234,"categories":235,"keywords":236,"publishedAt":44},"01M71AZ2KZNWYEGKKRMJH8PYG2","verify","Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fverify\u002FSKILL.md",[],[232,175,237,238,197,169,239,240,38,241,157,242,243,244,245],"commands","about","claims","output","assertions","claim","prs","evidence","running",{"skillNo":247,"name":248,"nameZh":6,"description":249,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":250,"categories":251,"keywords":252,"publishedAt":44},"01M71AZ0ACCK7N1QMWQK1FV2HJ","validate-idea","Validate a business idea using the minimalist entrepreneur framework. Use when someone has a business idea and wants to test if it's worth pursuing before building anything.","https:\u002F\u002Fgithub.com\u002Fariadoss\u002Fsuperskills\u002Fblob\u002Fmain\u002Fskills\u002Fvalidate-idea\u002FSKILL.md",[],[253,254,255,256,257,258,25,38,259,157,260],"validate","idea","validate idea","framework","it","minimalist","business","before building"]