[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6JPX9MVRDSEPYC50CHVSW14":3,"skill-same:01M6JPX9MVRDSEPYC50CHVSW14":98},{"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":37,"publishedAt":58,"linkOnly":59,"markdownContent":60,"markdownBody":61,"frontMatter":62,"refName":63,"commitSha":64,"skillDirectory":65,"forksCount":14,"repositoryHtmlUrl":66,"repositoryHomepageUrl":6,"ownerHtmlUrl":67,"ownerBlogUrl":6,"ownerDescription":68,"updatedAt":69,"install":70,"resources":83},"01M6JPX9MVRDSEPYC50CHVSW14","test-suite-design",null,"Design comprehensive test suites for existing code — strategy across unit\u002Fintegration\u002Fe2e, fixtures, factories, helpers. Triggers: add tests, write tests for, increase coverage, test this module, testing strategy, test plan, what tests do I need, test infrastructure, test helpers, this has no tests. Not for TDD — use tdd-workflow.","SWEStash\u002Fswe-workflow-skills","SWEStash","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F272895713?v=4","01M6JNRQ84JN5WFK9S1V5H4G46","SWE Stash","01M6JNRQCM45X8WPNHY30TSAB0",1,"MIT","https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fqa\u002Fskills\u002Ftest-suite-design\u002FSKILL.md",[18,23,26,29,34],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",{"categoryNo":35,"categoryName":36,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000032","设计师",[38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57],"design","test","test suite design","test suite","for","testing","unit","add","triggers","across","testing strategy","do","coverage","write","plan","test plan","code","infrastructure","write tests","workflow","2026-11-10 10:12:30",false,"---\nname: test-suite-design\ndescription: \"Design comprehensive test suites for existing code — strategy across unit\u002Fintegration\u002Fe2e, fixtures, factories, helpers. Triggers: add tests, write tests for, increase coverage, test this module, testing strategy, test plan, what tests do I need, test infrastructure, test helpers, this has no tests. Not for TDD — use tdd-workflow.\"\n---\n\n# Test Suite Design\n\nDesign and implement test suites for existing code. This is different from TDD: TDD drives *new* implementation through tests. This skill adds *meaningful test coverage* to code that already exists, designs test architecture, and builds test infrastructure.\n\n## When to Use This vs TDD\n\n| Situation | Use This Skill | Use tdd-workflow |\n|-----------|---------------|-----------------|\n| Existing module with no tests | ✓ | |\n| Building a new feature from scratch | | ✓ |\n| Planning overall test strategy for a project | ✓ | |\n| Increasing coverage on legacy code | ✓ | |\n| Fixing a bug (write regression test + fix) | | ✓ |\n| Designing test fixtures and factories | ✓ | |\n\n## Workflow\n\n### Step 1: Assess the Current State\n\nBefore writing any tests, understand what you're working with:\n\n- **What code needs testing?** A single function, a module, or a whole layer?\n- **What does the code do?** Read it and identify the behaviors (inputs → outputs, side effects, state changes)\n- **What's the risk profile?** Business-critical logic, data transformations, auth\u002Fsecurity, and integrations deserve tests first. Glue code and configuration deserve tests last.\n- **What test infrastructure exists?** Test runner, assertion library, mocking framework, fixtures, CI pipeline?\n- **What's the dependency situation?** Does the code have hard dependencies that make it difficult to test in isolation?\n\nIf there's no test infrastructure at all, start with Step 2. Otherwise, skip to Step 3.\n\n### Step 2: Set Up Test Infrastructure\n\nEstablish the foundation before writing individual tests:\n\n1. **Test runner and framework** — Choose based on the stack (Jest\u002FVitest for JS\u002FTS, pytest for Python, Go's built-in testing, JUnit for Java)\n2. **Directory structure** — Co-located (`foo.test.ts` next to `foo.ts`) or separate (`tests\u002F` directory). Recommend co-located for unit tests, separate directory for integration\u002Fe2e.\n3. **Shared helpers** — Create a `tests\u002Fhelpers\u002F` or `tests\u002Ffixtures\u002F` directory for reusable setup\n4. **CI integration** — Tests should run on every PR at minimum\n\nSee [references\u002Ftest-infrastructure.md](references\u002Ftest-infrastructure.md) for framework-specific setup patterns.\n\nThese four are choices to *state*, not questions to ask back. Pick the stack's conventional\nanswer, note it in a line, and keep going to Step 3 in the same response — infrastructure\ndecisions are cheap for the user to correct and expensive to wait for.\n\n### Step 3: Map Behaviors to Test\n\nFor each piece of code to test, create a behavior map — not a line-by-line mirror of the implementation, but a list of *what the code is supposed to do*:\n\n**For a function\u002Fmethod:**\n- What does it return for valid inputs? (happy path)\n- What happens with boundary values? (empty, zero, max, null)\n- What happens with invalid inputs? (wrong type, missing required fields)\n- What side effects does it produce? (database writes, API calls, events emitted)\n- What errors can it throw\u002Freturn? Under what conditions?\n\n**For a class\u002Fmodule:**\n- What are the key public methods and their contracts?\n- What state transitions are possible?\n- What invariants should always hold?\n- How do methods interact (does calling A affect the result of B)?\n\n**For an API endpoint:**\n- What responses for valid requests? (status codes, response shape)\n- What responses for invalid requests? (validation errors, 400\u002F401\u002F403\u002F404)\n- What auth\u002Fpermission checks exist?\n- What database state changes occur?\n\nWhen mapping behaviors, exclude behaviors that belong to a dependency — map *your* code's use of it (the inputs it passes, how it handles the library's outputs and errors), not the library's internals. \"gzip produces these magic bytes\" is zlib's behavior; \"our codec round-trips a value and falls back gracefully on a legacy plain string\" is ours.\n\n**Cover the failure branch you can see in the code.** The most common coverage hole in\nAI-assisted suites is a repair\u002Fparse\u002Ferror branch that's fully written but never tested,\nbecause every fixture feeds valid input so the branch never runs — and it's usually the\nriskiest branch (a fail-open handler that returns \"clean\" on parse failure ships\nunexercised). If the code has an `except`, a fallback, or a \"couldn't do it\" path, the\nbehavior map needs an entry that forces it.\n\nPresent the behavior map to the user and refine before writing tests.\n\n### Step 4: Choose the Testing Layer\n\nApply the testing pyramid — see [references\u002Ftesting-pyramid.md](references\u002Ftesting-pyramid.md):\n\n- **Unit tests**: Pure functions, business logic, transformations, validators. Fast, isolated, many of them.\n- **Integration tests**: Database queries, API endpoints, service interactions. Slower, need setup\u002Fteardown, fewer of them.\n- **E2E tests**: Critical user journeys only. Slowest, most brittle, fewest of them.\n\n**70\u002F20\u002F10 is a starting point, not the answer.** It assumes most behavior lives in\ncode you can call directly. Where the framework owns the behavior — an ORM-heavy\nDjango or Rails app whose logic is queries and view wiring — the honest split shifts\ntoward integration, because a unit test of a mocked queryset proves nothing. State the\ndistribution you are targeting **for this codebase** and say what about the codebase\nmoved it off the default.\n\nFor each behavior from Step 3, assign it to the appropriate layer. Default to the lowest (fastest) layer that can meaningfully test the behavior.\n\n### Step 5: Handle Untestable Code\n\nExisting code is often hard to test because of tight coupling. Common patterns and solutions:\n\n**Hard-coded dependencies** → Inject dependencies through constructor or function parameters. Refactor minimally to enable testing — just enough to inject a mock, not a full redesign.\n\n**Global state** → Isolate in a module you can mock. Or reset state in beforeEach\u002FsetUp.\n\n**Side effects mixed with logic** → Extract the pure logic into a separate testable function. Test the logic directly, test the side effects at the integration level.\n\n**External API calls** → Wrap in a client class\u002Fmodule. Mock the wrapper in unit tests. Test the wrapper itself in integration tests.\n\nIf refactoring is needed to make code testable, keep changes minimal. The goal is test coverage now, not architectural perfection. Deeper structural work belongs to the `refactoring` skill — see Cross-Skill References.\n\n### Step 6: Write the Tests\n\nWrite tests grouped by behavior, not by function. Use descriptive `describe`\u002F`context` blocks:\n\n```\ndescribe('OrderService')\n  describe('calculateTotal')\n    it('sums item prices for a standard order')\n    it('applies percentage discount when coupon is valid')\n    it('returns zero for an empty cart')\n    it('throws when item has negative price')\n  describe('placeOrder')\n    it('creates order record in database')\n    it('sends confirmation email')\n    it('rejects when inventory is insufficient')\n```\n\nFor each test, follow Arrange-Act-Assert. Keep tests focused — one behavior per test.\n\n**Write the tests out, in this same response.** Steps 1-5 are preparation, not a gate on\ndelivering — none of them is a reason to stop at a plan. A behavior map, a list of describe\nblocks, an `it.each` table shape, or \"tell me your runner and I'll write them\" is not a test\nsuite. If the runner is unknown, pick the stack's default (Jest\u002FVitest for JS\u002FTS, pytest for\nPython), say in one line that you assumed it, and write the tests anyway — the user can\ncorrect a framework far more cheaply than they can answer four questions to get anything at all.\n\nExit condition for this step: **runnable test bodies exist in your reply**, one per behavior\nmapped in Step 3, each with a name that reads as a specification (`it('returns 0 when the\norder has no items')`, not `it('test calculateShippingCost')` or `it('edge case 3')`) — so a\nfailure report names the broken behavior without anyone opening the file.\n\n### Step 7: Evaluate Coverage Quality\n\nAfter writing the suite, assess quality (not just line coverage percentage):\n\n- [ ] Are the critical paths tested? (payments, auth, data mutations)\n- [ ] Are error paths tested? (not just happy paths)\n- [ ] Do tests document behavior? (can you understand the module by reading only the tests?)\n- [ ] Are tests independent? (can run in any order)\n- [ ] Are tests deterministic? (no flakiness from timing, randomness, or external state)\n- [ ] Is the test-to-implementation coupling low? (can you refactor internals without breaking tests?)\n\nCoverage percentage is a floor, not a ceiling. 80% meaningful coverage beats 100% shallow coverage.\n\n## Pruning Test Slop\n\nSuites accumulate tests that cost maintenance without buying protection — common in AI-assisted codebases, where generated tests pad coverage. Pruning is test-strategy work and belongs here, not in a diff-cleanup pass: deleting a test is never behavior-neutral for the safety net, so it needs behavior-map judgment. A test is a removal candidate when it:\n\n- **Asserts nothing meaningful** — `expect(true).toBe(true)` filler, or assertions that cannot fail\n- **Hedged or non-falsifiable** — `assert x is None or x == []` (covers both, so nothing can fail it), `assert x in (\"skills\", \"work\")` when only one is reachable, or a test whose *name* claims more than its assertion checks (`test_multi_word_goes_to_work` that never asserts \"work\")\n- **Brittle on cosmetics** — pinned to CSS class strings, emoji, exact copy, or rendered-prompt prose, so a harmless reword reds the suite; assert a stable data attribute or the DOM\u002Fstructure instead\n- **Duplicates another test's coverage of the same behavior** — same arrange\u002Fact\u002Fassert in substance, differing only cosmetically\n- **Asserts on the mock rather than the code** — verifying that the mock returned what it was configured to return tests the mock, not the unit\n- **Mirrors the implementation line-for-line** — breaks on every refactor, catches no behavior change\n\nSeparately, watch for **setup\u002Ffixture duplication across files** — the same on-disk\nscaffold or `_make_x` builder copy-pasted into 5–19 test files because there's no\n`conftest.py` \u002F shared factory. That's not a pruning candidate (the tests are real); it's\na consolidation candidate — extract the shared fixture (Step 2), then have each file use\nit. Left alone, the copies drift and a setup change becomes an N-file edit.\n\nThe discipline: map the behaviors first (Step 3), then remove one test at a time, verifying after each removal that every behavior in the map is still covered by a remaining test. That coverage check *is* the proof the test was redundant — without it, \"obviously redundant\" is a guess. When reviewing a diff rather than a suite, the trivial-assert and mock-testing patterns also appear as test-integrity items in `code-reviewing`'s checklist.\n\n## Cross-Skill References\n\n- `refactoring` — **name this handoff whenever the goal of the coverage is a refactor.** The\n  suite is what makes the refactor safe: it pins current behavior so a structural change that\n  breaks something fails a test instead of reaching production. Say which tests have to be\n  green before the refactor starts, and that untested code should not be restructured.\n- `tdd-workflow` — for code that does not exist yet; this skill is for covering code that does\n- `test-data-strategy` — factories, fixtures, and synthetic data for the suite designed here\n- `code-archaeology` — when the current behavior is unclear, characterize it before pinning it\n\n## Principles Applied\n\n- **DRY in tests**: Share setup through fixtures\u002Ffactories, but keep each test readable on its own. A little repetition in tests is better than obscure shared state.\n- **KISS**: Test behavior, not implementation. Don't mirror the code structure 1:1 in tests.\n- **YAGNI**: Don't test trivial code (getters, delegating wrappers). Focus coverage where bugs hide.\n- **Test your code, not your dependencies**: Assert what *your* code does with a library, not what the library does. A round-trip through your own `pack`\u002F`unpack` wrapper is your logic; asserting a compression lib's magic bytes or its compression ratio is re-testing zlib — the vendor's job, already covered by the vendor's tests. Verify third-party *integration* at the integration layer, not by re-testing the library.\n- **Functional Independence**: Each test should set up its own state and clean up after itself.\n","# Test Suite Design\n\nDesign and implement test suites for existing code. This is different from TDD: TDD drives *new* implementation through tests. This skill adds *meaningful test coverage* to code that already exists, designs test architecture, and builds test infrastructure.\n\n## When to Use This vs TDD\n\n| Situation | Use This Skill | Use tdd-workflow |\n|-----------|---------------|-----------------|\n| Existing module with no tests | ✓ | |\n| Building a new feature from scratch | | ✓ |\n| Planning overall test strategy for a project | ✓ | |\n| Increasing coverage on legacy code | ✓ | |\n| Fixing a bug (write regression test + fix) | | ✓ |\n| Designing test fixtures and factories | ✓ | |\n\n## Workflow\n\n### Step 1: Assess the Current State\n\nBefore writing any tests, understand what you're working with:\n\n- **What code needs testing?** A single function, a module, or a whole layer?\n- **What does the code do?** Read it and identify the behaviors (inputs → outputs, side effects, state changes)\n- **What's the risk profile?** Business-critical logic, data transformations, auth\u002Fsecurity, and integrations deserve tests first. Glue code and configuration deserve tests last.\n- **What test infrastructure exists?** Test runner, assertion library, mocking framework, fixtures, CI pipeline?\n- **What's the dependency situation?** Does the code have hard dependencies that make it difficult to test in isolation?\n\nIf there's no test infrastructure at all, start with Step 2. Otherwise, skip to Step 3.\n\n### Step 2: Set Up Test Infrastructure\n\nEstablish the foundation before writing individual tests:\n\n1. **Test runner and framework** — Choose based on the stack (Jest\u002FVitest for JS\u002FTS, pytest for Python, Go's built-in testing, JUnit for Java)\n2. **Directory structure** — Co-located (`foo.test.ts` next to `foo.ts`) or separate (`tests\u002F` directory). Recommend co-located for unit tests, separate directory for integration\u002Fe2e.\n3. **Shared helpers** — Create a `tests\u002Fhelpers\u002F` or `tests\u002Ffixtures\u002F` directory for reusable setup\n4. **CI integration** — Tests should run on every PR at minimum\n\nSee [references\u002Ftest-infrastructure.md](references\u002Ftest-infrastructure.md) for framework-specific setup patterns.\n\nThese four are choices to *state*, not questions to ask back. Pick the stack's conventional\nanswer, note it in a line, and keep going to Step 3 in the same response — infrastructure\ndecisions are cheap for the user to correct and expensive to wait for.\n\n### Step 3: Map Behaviors to Test\n\nFor each piece of code to test, create a behavior map — not a line-by-line mirror of the implementation, but a list of *what the code is supposed to do*:\n\n**For a function\u002Fmethod:**\n- What does it return for valid inputs? (happy path)\n- What happens with boundary values? (empty, zero, max, null)\n- What happens with invalid inputs? (wrong type, missing required fields)\n- What side effects does it produce? (database writes, API calls, events emitted)\n- What errors can it throw\u002Freturn? Under what conditions?\n\n**For a class\u002Fmodule:**\n- What are the key public methods and their contracts?\n- What state transitions are possible?\n- What invariants should always hold?\n- How do methods interact (does calling A affect the result of B)?\n\n**For an API endpoint:**\n- What responses for valid requests? (status codes, response shape)\n- What responses for invalid requests? (validation errors, 400\u002F401\u002F403\u002F404)\n- What auth\u002Fpermission checks exist?\n- What database state changes occur?\n\nWhen mapping behaviors, exclude behaviors that belong to a dependency — map *your* code's use of it (the inputs it passes, how it handles the library's outputs and errors), not the library's internals. \"gzip produces these magic bytes\" is zlib's behavior; \"our codec round-trips a value and falls back gracefully on a legacy plain string\" is ours.\n\n**Cover the failure branch you can see in the code.** The most common coverage hole in\nAI-assisted suites is a repair\u002Fparse\u002Ferror branch that's fully written but never tested,\nbecause every fixture feeds valid input so the branch never runs — and it's usually the\nriskiest branch (a fail-open handler that returns \"clean\" on parse failure ships\nunexercised). If the code has an `except`, a fallback, or a \"couldn't do it\" path, the\nbehavior map needs an entry that forces it.\n\nPresent the behavior map to the user and refine before writing tests.\n\n### Step 4: Choose the Testing Layer\n\nApply the testing pyramid — see [references\u002Ftesting-pyramid.md](references\u002Ftesting-pyramid.md):\n\n- **Unit tests**: Pure functions, business logic, transformations, validators. Fast, isolated, many of them.\n- **Integration tests**: Database queries, API endpoints, service interactions. Slower, need setup\u002Fteardown, fewer of them.\n- **E2E tests**: Critical user journeys only. Slowest, most brittle, fewest of them.\n\n**70\u002F20\u002F10 is a starting point, not the answer.** It assumes most behavior lives in\ncode you can call directly. Where the framework owns the behavior — an ORM-heavy\nDjango or Rails app whose logic is queries and view wiring — the honest split shifts\ntoward integration, because a unit test of a mocked queryset proves nothing. State the\ndistribution you are targeting **for this codebase** and say what about the codebase\nmoved it off the default.\n\nFor each behavior from Step 3, assign it to the appropriate layer. Default to the lowest (fastest) layer that can meaningfully test the behavior.\n\n### Step 5: Handle Untestable Code\n\nExisting code is often hard to test because of tight coupling. Common patterns and solutions:\n\n**Hard-coded dependencies** → Inject dependencies through constructor or function parameters. Refactor minimally to enable testing — just enough to inject a mock, not a full redesign.\n\n**Global state** → Isolate in a module you can mock. Or reset state in beforeEach\u002FsetUp.\n\n**Side effects mixed with logic** → Extract the pure logic into a separate testable function. Test the logic directly, test the side effects at the integration level.\n\n**External API calls** → Wrap in a client class\u002Fmodule. Mock the wrapper in unit tests. Test the wrapper itself in integration tests.\n\nIf refactoring is needed to make code testable, keep changes minimal. The goal is test coverage now, not architectural perfection. Deeper structural work belongs to the `refactoring` skill — see Cross-Skill References.\n\n### Step 6: Write the Tests\n\nWrite tests grouped by behavior, not by function. Use descriptive `describe`\u002F`context` blocks:\n\n```\ndescribe('OrderService')\n  describe('calculateTotal')\n    it('sums item prices for a standard order')\n    it('applies percentage discount when coupon is valid')\n    it('returns zero for an empty cart')\n    it('throws when item has negative price')\n  describe('placeOrder')\n    it('creates order record in database')\n    it('sends confirmation email')\n    it('rejects when inventory is insufficient')\n```\n\nFor each test, follow Arrange-Act-Assert. Keep tests focused — one behavior per test.\n\n**Write the tests out, in this same response.** Steps 1-5 are preparation, not a gate on\ndelivering — none of them is a reason to stop at a plan. A behavior map, a list of describe\nblocks, an `it.each` table shape, or \"tell me your runner and I'll write them\" is not a test\nsuite. If the runner is unknown, pick the stack's default (Jest\u002FVitest for JS\u002FTS, pytest for\nPython), say in one line that you assumed it, and write the tests anyway — the user can\ncorrect a framework far more cheaply than they can answer four questions to get anything at all.\n\nExit condition for this step: **runnable test bodies exist in your reply**, one per behavior\nmapped in Step 3, each with a name that reads as a specification (`it('returns 0 when the\norder has no items')`, not `it('test calculateShippingCost')` or `it('edge case 3')`) — so a\nfailure report names the broken behavior without anyone opening the file.\n\n### Step 7: Evaluate Coverage Quality\n\nAfter writing the suite, assess quality (not just line coverage percentage):\n\n- [ ] Are the critical paths tested? (payments, auth, data mutations)\n- [ ] Are error paths tested? (not just happy paths)\n- [ ] Do tests document behavior? (can you understand the module by reading only the tests?)\n- [ ] Are tests independent? (can run in any order)\n- [ ] Are tests deterministic? (no flakiness from timing, randomness, or external state)\n- [ ] Is the test-to-implementation coupling low? (can you refactor internals without breaking tests?)\n\nCoverage percentage is a floor, not a ceiling. 80% meaningful coverage beats 100% shallow coverage.\n\n## Pruning Test Slop\n\nSuites accumulate tests that cost maintenance without buying protection — common in AI-assisted codebases, where generated tests pad coverage. Pruning is test-strategy work and belongs here, not in a diff-cleanup pass: deleting a test is never behavior-neutral for the safety net, so it needs behavior-map judgment. A test is a removal candidate when it:\n\n- **Asserts nothing meaningful** — `expect(true).toBe(true)` filler, or assertions that cannot fail\n- **Hedged or non-falsifiable** — `assert x is None or x == []` (covers both, so nothing can fail it), `assert x in (\"skills\", \"work\")` when only one is reachable, or a test whose *name* claims more than its assertion checks (`test_multi_word_goes_to_work` that never asserts \"work\")\n- **Brittle on cosmetics** — pinned to CSS class strings, emoji, exact copy, or rendered-prompt prose, so a harmless reword reds the suite; assert a stable data attribute or the DOM\u002Fstructure instead\n- **Duplicates another test's coverage of the same behavior** — same arrange\u002Fact\u002Fassert in substance, differing only cosmetically\n- **Asserts on the mock rather than the code** — verifying that the mock returned what it was configured to return tests the mock, not the unit\n- **Mirrors the implementation line-for-line** — breaks on every refactor, catches no behavior change\n\nSeparately, watch for **setup\u002Ffixture duplication across files** — the same on-disk\nscaffold or `_make_x` builder copy-pasted into 5–19 test files because there's no\n`conftest.py` \u002F shared factory. That's not a pruning candidate (the tests are real); it's\na consolidation candidate — extract the shared fixture (Step 2), then have each file use\nit. Left alone, the copies drift and a setup change becomes an N-file edit.\n\nThe discipline: map the behaviors first (Step 3), then remove one test at a time, verifying after each removal that every behavior in the map is still covered by a remaining test. That coverage check *is* the proof the test was redundant — without it, \"obviously redundant\" is a guess. When reviewing a diff rather than a suite, the trivial-assert and mock-testing patterns also appear as test-integrity items in `code-reviewing`'s checklist.\n\n## Cross-Skill References\n\n- `refactoring` — **name this handoff whenever the goal of the coverage is a refactor.** The\n  suite is what makes the refactor safe: it pins current behavior so a structural change that\n  breaks something fails a test instead of reaching production. Say which tests have to be\n  green before the refactor starts, and that untested code should not be restructured.\n- `tdd-workflow` — for code that does not exist yet; this skill is for covering code that does\n- `test-data-strategy` — factories, fixtures, and synthetic data for the suite designed here\n- `code-archaeology` — when the current behavior is unclear, characterize it before pinning it\n\n## Principles Applied\n\n- **DRY in tests**: Share setup through fixtures\u002Ffactories, but keep each test readable on its own. A little repetition in tests is better than obscure shared state.\n- **KISS**: Test behavior, not implementation. Don't mirror the code structure 1:1 in tests.\n- **YAGNI**: Don't test trivial code (getters, delegating wrappers). Focus coverage where bugs hide.\n- **Test your code, not your dependencies**: Assert what *your* code does with a library, not what the library does. A round-trip through your own `pack`\u002F`unpack` wrapper is your logic; asserting a compression lib's magic bytes or its compression ratio is re-testing zlib — the vendor's job, already covered by the vendor's tests. Verify third-party *integration* at the integration layer, not by re-testing the library.\n- **Functional Independence**: Each test should set up its own state and clean up after itself.\n",{"name":5,"description":7},"main","800dc9ad0ca2914d6ad15b8c5159d9b57bb104c2","plugins\u002Fqa\u002Fskills\u002Ftest-suite-design","https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills","https:\u002F\u002Fgithub.com\u002FSWEStash","A stash of things we felt like building","2026-11-11 09:15:32",{"source":8,"skillName":5,"commands":71,"prompt":81,"zipAvailable":82},[72,75,78],{"tool":73,"command":74},"npx","npx skills add SWEStash\u002Fswe-workflow-skills --skill test-suite-design",{"tool":76,"command":77},"bunx","bunx skills add SWEStash\u002Fswe-workflow-skills --skill test-suite-design",{"tool":79,"command":80},"pnpm","pnpm dlx skills add SWEStash\u002Fswe-workflow-skills --skill test-suite-design","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fqa\u002Fskills\u002Ftest-suite-design\u002FSKILL.md",true,[84,90,94],{"path":85,"resourceType":86,"resourceTypeDesc":87,"sizeBytes":88,"sourceHtmlUrl":89},"evals\u002Fevals.json","REFERENCE","参考文档",8245,"https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fqa\u002Fskills\u002Ftest-suite-design\u002Fevals\u002Fevals.json",{"path":91,"resourceType":86,"resourceTypeDesc":87,"sizeBytes":92,"sourceHtmlUrl":93},"references\u002Ftest-infrastructure.md",3890,"https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fqa\u002Fskills\u002Ftest-suite-design\u002Freferences\u002Ftest-infrastructure.md",{"path":95,"resourceType":86,"resourceTypeDesc":87,"sizeBytes":96,"sourceHtmlUrl":97},"references\u002Ftesting-pyramid.md",5728,"https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fqa\u002Fskills\u002Ftest-suite-design\u002Freferences\u002Ftesting-pyramid.md",[99,134,160,183,211,238],{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":116,"publishedAt":58},"01M6JQFADV3T1MS9V1BNZS1232","writing-skills","Use when authoring, editing, or reviewing a skill in this library — a new SKILL.md, one that under-triggers, or hardening an existing one. Covers description and listing-budget rules, frontmatter, progressive disclosure, the 3-eval rule, and pressure-testing against rationalizations.","https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fskills\u002Fwriting-skills\u002FSKILL.md",[105,106,109,110,113],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":107,"categoryName":108,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":111,"categoryName":112,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000036","内容创作者",{"categoryNo":114,"categoryName":115,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000040","财务",[117,118,43,119,51,120,121,122,123,124,125,126,46,127,128,129,130,131,132,133],"writing","writing skills","eval","edit","Budget","authoring","new skill","library","frontmatter","editing","use","Existing","Rules","write a skill","when","listing","progressive disclosure",{"skillNo":135,"name":136,"nameZh":6,"description":137,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":138,"categories":139,"keywords":141,"publishedAt":58},"01M6JQF5DGMXPMQQVZBP8DH9SY","working-agreement","Define and validate how a multi-session project is run — where plans, status and decisions live, session routines, new work, milestone close. README\u002FCONTRIBUTING → project-documentation.","https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fskills\u002Fworking-agreement\u002FSKILL.md",[140],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,49,157,158,46,159],"working agreement","project","definition of done","done","milestone","documentation","work","progress","how","contributing","close","run","sync","status","live","README","session","routines",{"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":167,"publishedAt":58},"01M6JQF0SMRHN82RBSWMABC4J0","verification-before-completion","Evidence gate before any claim that work is done, fixed, passing, or deployed. Route here when a message declares the work finished or asks to commit, push, merge, ship, or close it out, including a brief sign-off, and before git-workflow or release-management act on it. Writing the commit message or PR text itself → git-workflow.","https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fskills\u002Fverification-before-completion\u002FSKILL.md",[166],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[168,169,170,171,172,173,117,57,145,174,175,176,148,177,152,178,179,180,181,182],"verification","verification before completion","brief","ready","fix","claim","commit","text","route","message","merge","release","git","act","ship",{"skillNo":184,"name":185,"nameZh":6,"description":186,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":187,"categories":188,"keywords":192,"publishedAt":58},"01M6JQEVGE9NJZ11DV60AE6VWC","ui-ux-design","Design user experiences from an engineer's perspective — user flows, wireframes, interaction patterns, responsive strategy, navigation, loading\u002Ferror\u002Fempty states. Triggers: design the UI, user flow, wireframe, how should this screen look, loading state, error state, empty state, responsive design, navigation, page layout, form design, mockup.","https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fskills\u002Fui-ux-design\u002FSKILL.md",[189,190,191],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":35,"categoryName":36,"taxonomyType":32,"taxonomyTypeDesc":33},[38,193,194,195,196,197,198,199,200,201,202,203,150,204,205,206,207,208,209,210],"ux","ui","ui ux design","error","states","loading","flows","engineer","interaction","layout","responsive design","screen","flow","patterns","mockup","responsive","form","page",{"skillNo":212,"name":213,"nameZh":6,"description":214,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":215,"categories":216,"keywords":219,"publishedAt":58},"01M6JQEN4HVFTZWQYWGTDS76K9","threat-modeling","Design-time security analysis of a system or feature before it's built — trust boundaries, attack surface, STRIDE per element, abuse cases, prioritized mitigations that become security requirements. Triggers: threat model, STRIDE, trust boundary, attack surface, what could go wrong security-wise, security design review, abuse case, secure this design, security requirements. Reviewing EXISTING code\u002Fconfig for vulnerabilities → security-audit; use this skill while the design is still on the whiteboard.","https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fskills\u002Fthreat-modeling\u002FSKILL.md",[217,218],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},[220,221,222,223,224,225,38,226,227,228,54,229,230,231,232,233,234,235,236,237],"modeling","threat modeling","threat","model","time","element","whiteboard","security analysis","analysis","review","threat model","audit","security-audit","secure","config","go","security","trust",{"skillNo":239,"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":240,"categories":241,"keywords":247,"publishedAt":58},"01M6JQEFT7VT3FQM16170EG9FW","https:\u002F\u002Fgithub.com\u002FSWEStash\u002Fswe-workflow-skills\u002Fblob\u002Fmain\u002Fskills\u002Ftest-suite-design\u002FSKILL.md",[242,243,244,245,246],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},{"categoryNo":35,"categoryName":36,"taxonomyType":32,"taxonomyTypeDesc":33},[38,41,39,40,50,44,43,56,48,57,54,47,52,51,45,55,49,53,42,46]]