| name | test-gen |
| description | Generate frontend tests by deciding which parts belong in unit tests and which belong in end-to-end (e2e) tests, then writing runnable test code that matches the project's existing stack. Framework-agnostic: works with Vue or React, Vitest or Jest, Playwright or Cypress, with or without MSW.
生成前端测试:把要测的内容拆开,判定哪些写单测、哪些写 e2e,再按项目现有技术栈产出可直接运行的测试代码。框架无关,自动适配项目已有的 runner 与组件框架。
Use this skill whenever the user wants to:
- "/test-gen", "生成测试", "写测试 / 写单测 / 写 e2e", "补测试", "add tests", "write tests for this", "how should I test this"
- paste a feature description, requirement, user flow, test case, or source file and ask for tests
- ask "should this be a unit test or e2e", "帮我拆一下测试", split testing responsibilities
Trigger even when the user does not explicitly say "unit" or "e2e" — any request to add automated verification for frontend behavior should use this skill.
|
test-gen
Translate "what needs to be verified" into "which kind of test + runnable code". Two jobs: decide unit vs e2e, and write tests that match the project's existing conventions.
One sentence behind every decision: unit tests guard the parts, e2e guards that the assembled whole actually works. Most frontend bugs are not "computed wrong" but "wired wrong" — data flows from an API through a store, through derived state, down to some component's class, and any broken assumption in that chain passes every unit test while the page breaks on click. e2e covers exactly that. This matters even more for AI-written code, whose understanding is local and which most easily produces "every part green, assembled it crashes".
Workflow
This skill expects parallel execution across multiple contexts. Detection, generation, and self-check are independent kinds of work — fan them out with subagents instead of doing everything serially. Each step notes what to parallelize.
Step 0 · Detect the project's test stack (parallelizable)
Never assume the stack. Launch read-only subagents in parallel to determine:
- Component framework: Vue 3 / React / other (check
package.json deps, file extensions).
- Unit runner: Vitest / Jest (config files, scripts). Env: jsdom / happy-dom / node.
- e2e runner: Playwright / Cypress (config,
e2e/ or cypress/ dirs).
- Network mocking: MSW present? a shared fixtures/mock package? Or per-test mocks?
- Reusable assets: existing test helpers, fixtures,
e2e/helpers.*, mount helpers, naming conventions, where tests live.
If the project has no test setup at all, tell the user to run /test-setup first, then come back.
Record the detected stack — every generated file must match it. The decision framework is universal; only the syntax of the generated code depends on the stack.
Step 1 · Parse input into verifiable units
Input may be a plain-language test case, a requirement, a component/function file, or a user flow. Break it into the smallest verifiable points — each answering "given this input/precondition, what observable result is expected".
Separate two kinds:
- Part-level: pure functions I/O, store actions/getters, composable/hook state transitions, a single component's render/events given props.
- Assembly-level: behavior crossing store → derived state → multiple components → API → render; failure/edge/retry/limit paths; streaming render, overlay enter/exit, real interaction timing.
Step 2 · Decide unit vs e2e
Classify each verifiable point with the framework below. If you cannot decide confidently, do not guess — go to Step 3 and ask. Read references/decision-framework.md for full rules, signals, and worked examples before concluding.
Quick reference:
| Signal | Leans | Why |
|---|
| Pure logic, computation, data transform | Unit | A part; deterministic I/O; fastest, most stable |
| Store action/getter, composable/hook state | Unit | Call directly or mount in isolation |
| Single component render/events/branches given props | Unit | Isolated component test |
| A user "clicks through" flow across components/store/API | e2e | Assembled whole; catches the "wired wrong" units miss |
| Failure, timeout, retry, limit, stream interruption | e2e | Network-layer mock reproduces deterministically |
| Overlay enter/exit, streaming render, real interaction timing | e2e | Closest to a real user, hardest to fool |
| Heavy third-party DOM/canvas/rich-text integration | Consider excluding | Low cost/benefit to hard-test; exclude from coverage |
Most features need both: parts covered by unit tests, key flows and failure paths locked by e2e. Tell the user how each point was classified and why.
Step 3 · Ask when unclear (use structured questions)
Whenever an uncertainty would affect test correctness, stop and ask rather than hallucinating an assertion. Typical cases:
- The real current behavior is unclear (assert current state vs ideal spec — see Principles).
- The API shape/fields/response is unknown and no fixture exists.
- The precondition to reach the target UI is unclear (auth, seeded data, a dev/debug entry).
- Failure/edge-path copy or UI is uncertain.
- Whether the feature is "not worth hard-testing / exclude from coverage" is unclear.
Offer concrete options with a recommendation. Record the resolution in the final report.
Step 4 · Generate test code in parallel (multiple contexts)
Once classified, fan out generation by independent artifact (use generalPurpose subagents), e.g.:
- Subagent A: unit tests for the module (in the project's unit-test location).
- Subagent B: e2e specs + any needed helpers.
- Subagent C: shared fixtures / mocks (all mock data lives in one shared source, reused by unit and e2e — never fork a second copy inside the app).
Each subagent's brief must include: the detected stack, the relevant references/conventions-*.md, the reusable assets found in Step 0, and the "assert current real behavior" principle. Follow references/conventions-unit.md, references/conventions-e2e.md, and references/mocking.md for syntax.
If artifacts depend on each other (e.g. an e2e spec needs a new fixture), produce fixtures first, then specs. Fan out everything independent in the same batch.
Step 5 · Self-check and run
Back in the main context:
- Run the unit tests for the affected package.
- Run the e2e tests (install browsers first if needed).
- If red: first suspect an assertion locked to "ideal spec" instead of current behavior, or an unmocked request (strict mock modes fail loudly on purpose).
- Lint the new files and fix issues.
Core principles (pass these to every subagent)
- Assert "current real behavior", not "ideal product spec". A test's first job is regression protection — catching "I broke it by accident". If code reality differs from the product's intended spec, assert reality and add a comment: "if product changes to X, update here". Asserting the ideal spec makes the test red from day one; red-until-numb means a dead test.
- Single source of mock data: fixtures live in one shared place, reused by unit and e2e. Change the API contract in one spot.
- Unmocked requests should fail loudly (e.g. MSW
onUnhandledRequest: 'error'; e2e intercept at the network layer). A silently-passing test that hit a real backend is worse than no test.
- Write e2e in "human language": test names describe user-visible behavior; extract repeated steps into helpers.
- Prioritize failure and edge paths — this is where e2e shines and manual testing can't give determinism.
Output report
## Test generation report
### Detected stack
- Framework / unit runner / e2e runner / mocking
### Breakdown & classification
| Verifiable point | Type | Target file | Reason |
|---|---|---|---|
### Files added/changed
- unit / e2e / fixtures
### Clarifications (if asked)
- Q / A
### How to run
- unit: ...
- e2e: ...
### Run result
- unit: X passed / e2e: X passed
### Reuse check
Checked <existing fixtures / helpers / tests>; reused ...; did not reuse because ...
Reference files
references/decision-framework.md — Full unit-vs-e2e rules, signals, and worked examples. Read before concluding.
references/conventions-unit.md — Unit/component test templates for Vitest & Jest (Vue & React).
references/conventions-e2e.md — e2e templates for Playwright (and Cypress notes).
references/mocking.md — The single-source-fixtures pattern: MSW (unit) + network interception (e2e) sharing one fixture set.