Code Testing Generation Skill
An AI-powered skill that generates comprehensive, workable unit tests for any programming language using a coordinated multi-agent pipeline.
ALWAYS USE whenever asked to write, add, or generate unit tests for existing code in xUnit, MSTest, NUnit, pytest, Vitest/Jest, Go, or another framework, including "tests only for" one helper, function, class, or missing regression case as well as project-wide suites. Also use for "cover this untested method", scaffolding tests where none exist, sparse workspaces, classic packages.config MSTest, and extending healthy suites. Focused requests use a proportional direct workflow; broad requests use the full pipeline. DO NOT USE for only running/diagnosing tests, coverage/audits, a test blocked on a missing production seam (testability-obstacle), or correcting supplied MSTest assertions, attributes, lifecycle, or configuration without designing new cases (writing-mstest-tests).
Permissions
Files
ALWAYS USE whenever asked to write, add, or generate unit tests for existing code in xUnit, MSTest, NUnit, pytest, Vitest/Jest, Go, or another framework, including "tests only for" one helper, function, class, or missing regression case as well as project-wide suites. Also use for "cover this untested method", scaffolding tests where none exist, sparse workspaces, classic packages.config MSTest, and extending healthy suites. Focused requests use a proportional direct workflow; broad requests use the full pipeline. DO NOT USE for only running/diagnosing tests, coverage/audits, a test blocked on a missing production seam (testability-obstacle), or correcting supplied MSTest assertions, attributes, lifecycle, or configuration without designing new cases (writing-mstest-tests).
An AI-powered skill that generates comprehensive, workable unit tests for any programming language using a coordinated multi-agent pipeline.
Version history
Classify scope before editing:
research.md and plan.md in a resolved
non-stageable <TESTAGENT_DIR> before implementation, then status.md there
after the final test-quality review. When code-testing-generator is
available, invoke that named custom agent before implementing; do not replace
it with a generic subagent carrying the same label or implement the broad
request inline. If the state files are absent, the broad workflow is
incomplete.For either scope, run the narrowest relevant test command to a clean exit.
Keep the handoff proportional: for one to three focused requirements, use a
compact bullet list under a Requirement coverage label that names the tests
and successful command; for broader or multi-requirement work, use a
Requirement | Evidence table. Each requested behavior must cite an exact test
name.
Intermediate state files are internal working data, never deliverables. Keep
<TESTAGENT_DIR> non-stageable, never place it or its files in
version-controlled workspace content, and never modify .gitignore to hide
them.
Treat completeness as a requirement matrix, not a test-count target. Give every independently requested state, boundary, error path, or interaction its own concrete assertion. Combine cases only when one execution genuinely proves the whole requested combination; do not let a parameterized happy-path case stand in for an empty state, invalid discriminator, or before/at/after boundary. For broad requests that name several production modules or layers, give each named module direct tests for its non-trivial public behavior. Cross-module tests prove composition, but do not substitute for the requested module-level coverage. Judge breadth by the behavior matrix, never by matching or exceeding a raw test count.
For a broad or comprehensive request, the explicit matrix is the floor, not the ceiling. Treat each requested module or layer as an inventory heading, not one behavior: expand it into the bounded public operations and their distinct validation paths, branches, boundaries, interactions, and state transitions. After satisfying the explicit matrix, inspect each target API for observable equivalence partitions and invariants that the prompt did not name: identity, empty, singleton and representative interior inputs; exact boundaries plus an immediately adjacent value; invalid partitions; and ordering, monotonicity, rollover, capacity, truncation, or state invariants implied by the implementation. Add one mutation-relevant case per distinct partition not already proved, using parameterized or table-driven cases only for siblings that prove the same behavior. A passing coverage threshold is validation, not a breadth stop condition. Stop when remaining inputs exercise the same branch and invariant, not merely when the explicit checklist is complete; never add cases only to raise the count.
Use this skill when you need to:
writing-mstest-tests as supporting
guidance after this entry skill has established scope and project conventionsrun-tests skill)writing-mstest-tests)This skill coordinates multiple specialized agents in a Research → Plan → Implement pipeline:
┌─────────────────────────────────────────────────────────────┐
│ TEST GENERATOR │
│ Coordinates the full pipeline and manages state │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────────┐
│ RESEARCHER│ │ PLANNER │ │ IMPLEMENTER │
│ │ │ │ │ │
│ Analyzes │ │ Creates │ │ Writes tests │
│ codebase │→ │ phased │→ │ per phase │
│ │ │ plan │ │ │
└───────────┘ └───────────┘ └───────┬───────┘
│
┌─────────┬───────┼───────────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌───────┐ ┌───────┐ ┌───────┐
│ BUILDER │ │TESTER │ │ FIXER │ │LINTER │
│ │ │ │ │ │ │ │
│ Compiles│ │ Runs │ │ Fixes │ │Formats│
│ code │ │ tests │ │ errors│ │ code │
└─────────┘ └───────┘ └───────┘ └───────┘
Make sure you understand what user is asking and for what scope. When the user does not express strong requirements for test style, coverage goals, or conventions, source the guidelines from unit-test-generation.prompt.md. This prompt provides best practices for discovering conventions, parameterization strategies, behavior-focused coverage, and language-specific patterns.
Match the machinery to the scope. Running the full pipeline on a one-file request costs turns and tool calls without improving the tests.
| Scope | What it looks like | How to run it |
|---|---|---|
| Focused | One function, class, or file; "tests for X only"; extending an existing suite with the missing cases | Skip intermediate state files and the sub-agent fan-out. Keep the requirement checklist in your head (or in the final table), read only the target and one neighbouring test for conventions, write the tests, run the narrowest test command, review your own assertions inline. |
| Broad | A project, package, or module set; "comprehensive suite"; a coverage threshold to clear across several files | Run the full Research → Plan → Implement pipeline in Step 3, with intermediate state files under <TESTAGENT_DIR> and the completion contract below. |
When in doubt, start focused and escalate only if the request turns out to span several files. Escalating costs one extra pass; running the broad pipeline on a focused request costs several.
Before ending a focused request, check all three conditions together:
Do not replace requirement-level evidence with a generic list of covered areas.
Start by invoking the named code-testing-generator custom agent with your test
generation request. Do not use a generic/general-purpose subagent merely named
code-testing-generator:
Generate unit tests for [path or description of what to test], following the [unit-test-generation.prompt.md](unit-test-generation.prompt.md) guidelines. Treat the current workspace as authoritative even when it is sparse, gutted-looking, synthetic, or missing tracked files; never restore or reconstruct it, including with `git checkout`, `git restore`, `git reset`, or `git clean`.
The Test Generator will manage the entire pipeline automatically.
If code-testing-generator is unavailable, do not skip the workflow. Execute the
same Research → Plan → Implement sequence inline, resolve <TESTAGENT_DIR> as
described below, create the intermediate state files there, and apply the same
completion contract.
For broad scope, resolve one absolute <TESTAGENT_DIR> before creating
intermediate state files:
git rev-parse --path-format=absolute --git-path testagent; this returns a
path in worktree-specific Git metadata that cannot be staged.Pass the absolute directory to every pipeline agent. The path may be inside the
repository's .git metadata directory, but it must not be version-controlled
workspace content, appear in git status, or be stageable.
For multi-file requests:
<TESTAGENT_DIR>/research.md.find-untested-sources once and consume its pairing and suggested-path output; do not repeat that discovery manually.code-testing-extensions only when the repository has no representative tests and the base extension is insufficient.packages.config, existing framework/mock versions and custom base fixtures, add every new test file to the project's explicit <Compile Include> items, and use the repository's MSBuild/test-runner commands. Never modernize the project or dependency stack merely to generate tests.Assert.ThrowsException<T>; do not substitute
[ExpectedException], Assert.Throws<T>, or Assert.ThrowsExactly<T>.Every scope must satisfy points 3–5 below. Points 1 and 2 are the broad-scope artifacts: on a focused request the same reasoning happens inline and no intermediate state files are written.
Do not report completion until all of these are true:
<TESTAGENT_DIR>/research.md records the bounded target
inventory, existing test conventions, and the acceptance checklist.<TESTAGENT_DIR>/plan.md maps each checklist item to a planned
test or an explicit blocker.test-gap-analysis and assertion-quality when available and
record the findings and fixes in <TESTAGENT_DIR>/status.md. On a focused scope,
do the equivalent review inline — re-read each generated assertion against
the source — without spawning extra passes.The final response must provide requirement-by-requirement evidence. Use compact
bullets under a Requirement coverage label for one to three focused
requirements; use a Requirement | Evidence table for broader scopes.
Behavioral evidence cites exact generated test names. Non-behavioral evidence
cites the relevant project file, validation command, or coverage report. A
generic list of tested areas is not a substitute.
Preserve the user's exact meaning in each evidence item; quote verbatim only when wording distinguishes a required combination. A test that merely exercises the same collaborators does not satisfy a requirement about their interaction, and per-class requirements need a citation per class.
Cite a clean run, not an attempt. The commands behind the final evidence must have finished successfully: quote the final passing test summary and, when thresholds were requested, the per-module coverage table from a run that exited 0. If the last coverage run exited non-zero, fix it and re-run before reporting; never infer threshold clearance from a failed or partial run.
Before reporting, inspect the final working-tree changes and confirm that
research.md, plan.md, status.md, and any other intermediate state files are
not among the changes intended for commit.
Broad-scope runs store intermediate state files in a non-stageable
<TESTAGENT_DIR> backed by host scratch storage, Git metadata, or OS temp. A
focused request does not create these files:
| File | Purpose |
|---|---|
<TESTAGENT_DIR>/research.md | Codebase analysis results |
<TESTAGENT_DIR>/plan.md | Phased implementation plan |
<TESTAGENT_DIR>/status.md | Final quality review and fixes |
| Agent | Purpose |
|---|---|
code-testing-generator | Coordinates pipeline |
code-testing-researcher | Analyzes codebase |
code-testing-planner | Creates test plan |
code-testing-implementer | Writes test files |
code-testing-builder | Compiles code |
code-testing-tester | Runs tests |
code-testing-fixer | Fixes errors |
code-testing-linter | Formats code |
Classic non-SDK .NET projects are supported when their existing build/test
toolchain is available. When it is not available on the current machine, the
agent can still add and register version-compatible tests, but must report
execution as blocked rather than substituting dotnet test.
The code-testing-fixer agent will attempt to resolve compilation errors. Check
<TESTAGENT_DIR>/plan.md for the expected test structure. Call the
code-testing-extensions skill and read the language-specific extension file
for error code references (e.g., dotnet.md for .NET).
Most failures in generated tests are caused by wrong expected values in assertions, not production code bugs:
[Ignore] or [Skip] just to make them passSpecify your preferred framework in the initial request: "Generate Jest tests for..."
Tests that depend on external services, network endpoints, specific ports, or precise timing will fail in CI environments. Focus on unit tests with mocked dependencies instead.
During implementation, build and test the narrow target. Run a solution or workspace-level command only for broad work, when the repository contract uses that entry point, or when the targeted change can affect other projects. Do not turn a focused test request into an unconditional full non-incremental build.
In these kits
More from @dotnet
Works with
Claude, Codex, Cursor & more