Test Scaffolder
Scaffold a test file with sensible cases for a given module or function. Use when adding tests to untested code and you want a fast, structured starting point.
npx agentscamp add skills/test-scaffolderInstall to ~/.claude/skills/test-scaffolder/SKILL.md
A skill that scaffolds a ready-to-run test file for a module or function with no coverage: it reads the target's public surface, detects the project's test framework, naming, and assertion style, enumerates happy-path, boundary, and error cases, writes the suite with clear names and stubbed dependencies, then runs it to confirm it executes.
Generate a ready-to-run test file for a module or function that currently has no coverage. The skill reads the target source, infers its public surface and likely edge cases, picks the project's existing test framework and conventions, and writes a focused suite of meaningful cases — happy path, boundaries, and error handling — so you start from a real structure instead of a blank file.
When to use this skill
- You are adding tests to previously untested code and want a fast, structured starting point.
- A new function or module needs a baseline suite before you refine specific cases.
- You want consistency with the repo's existing framework, file naming, and assertion style.
NOTE
This scaffolds a strong starting point — not a guarantee of correctness. Always read the generated assertions and confirm they encode the behavior you actually want before relying on them.
Instructions
- Locate the target. Read the file the user named. Identify the exported/public functions, classes, and their signatures. Note parameter types, return types, thrown errors, and any side effects (I/O, network, state mutation).
- Detect the test stack. Inspect the project to match conventions — do not guess:
- Check
package.json(jest,vitest,mocha),pytest.ini/pyproject.toml,go.mod, etc. - Mirror the existing test file location and naming (e.g.
__tests__/,*.test.ts,*_test.py,foo_test.go). - Match the assertion and mocking style already used in neighboring tests.
- Check
- Enumerate cases per unit. For each function, derive: the happy path, boundary inputs (empty, zero, max, null/undefined), invalid input that should throw, and any documented branches. Prefer a few meaningful cases over many trivial ones.
- Write the file. Create the test file at the conventional path with correct imports, a
describe/it(or framework-equivalent) block per unit, and clear test names stating the expected behavior. Stub external dependencies; leave a// TODOonly where a value genuinely needs human judgment. - Verify it runs. Run the suite (e.g.
npx vitest run path). Fix import/syntax errors so the file executes. Failing assertions that reveal real behavior are acceptable — flag them; broken scaffolding is not. - Report. Summarize the cases covered and call out any gaps (untested branches, hard-to-mock dependencies) the user should address next.
WARNING
Do not assert on implementation details (private helpers, internal call order) unless asked. Test observable behavior through the public API so the suite survives refactors.
Examples
Given src/utils/slugify.ts:
export function slugify(input: string): string {
if (typeof input !== "string") throw new TypeError("input must be a string");
return input.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
}The skill detects Vitest and writes src/utils/slugify.test.ts:
import { describe, it, expect } from "vitest";
import { slugify } from "./slugify";
describe("slugify", () => {
it("lowercases and hyphenates words", () => {
expect(slugify("Hello World")).toBe("hello-world");
});
it("collapses runs of non-alphanumerics into one hyphen", () => {
expect(slugify("a -- b!!c")).toBe("a-b-c");
});
it("trims leading and trailing hyphens", () => {
expect(slugify(" !Hi! ")).toBe("hi");
});
it("returns an empty string for symbol-only input", () => {
expect(slugify("###")).toBe("");
});
it("throws TypeError on non-string input", () => {
// @ts-expect-error testing runtime guard
expect(() => slugify(42)).toThrow(TypeError);
});
});Run it with npx vitest run src/utils/slugify.test.ts, then refine the assertions to match your intended behavior.
Related
- Contract Test DesignerDesign consumer-driven contract tests between services so an API provider can't break its consumers unnoticed — without slow, flaky full end-to-end environments. Use when independent services or teams integrate over an API, when integration bugs only surface in staging or prod, or when E2E suites are too slow and brittle to catch breaking API changes.
- Coverage Gap FinderRun the project's coverage tool and identify the highest-value untested paths — error branches, edge cases, and critical modules — then propose specific test cases for each gap. Use when you have a coverage report but don't know where new tests will pay off most.
- Integration Test DesignerDesign integration tests that exercise components against REAL collaborators — actual database, queue, HTTP boundary — at a deliberately chosen seam, instead of a unit suite that mocks everything or a slow flaky full E2E. Use when bugs slip past green unit tests, when wiring or contracts between layers break in production, or when a mocked DB test passes but the real query/migration/serialization fails.
- Mock Data FactoryGenerate a typed mock/fixture factory for a given type, interface, or schema, inferring believable values from field names and types. Use when tests or local dev need realistic, type-safe sample data with per-field overrides.
- Property Test DesignerDesign property-based tests — generate hundreds of random inputs and assert invariants that must hold for ALL of them — to surface the edge cases hand-picked examples never reach. Use when code has a large input space (parsers, serializers, encoders, math, data transforms), when a bug keeps slipping through despite green example tests, or when you can't enumerate every case worth checking.
- Writing Your First SkillA step-by-step guide to packaging a reusable procedure as a Claude Code skill that loads exactly when it's needed.
- TDD with AI Agents: Red-Green as an Agent LoopTest-driven development found its killer app: agents. How write-the-test-first turns AI coding into a verifiable loop, and the workflow that makes it stick.
- How to Test AI-Generated CodeAI writes the code; tests decide whether to trust it. The verification stack for agent-written changes — contracts, generated tests, and the review that's left.