Unit Test Writer
Generates comprehensive unit tests for any function or module with edge cases.
Best use case
Unit Test Writer is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Generates comprehensive unit tests for any function or module with edge cases.
Teams using Unit Test Writer should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/unit-test-writer/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How Unit Test Writer Compares
| Feature / Agent | Unit Test Writer | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Generates comprehensive unit tests for any function or module with edge cases.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Unit Test Writer
## What this skill does
This skill directs the agent to write a thorough unit test suite for a given function, class, or module. It systematically identifies happy paths, edge cases, error paths, and boundary conditions — then writes tests in your chosen framework (Jest, Vitest, Mocha, etc.) with proper mocking where needed.
Use this when you have a function that needs test coverage or when you want to verify your implementation handles edge cases you might not have thought of.
## How to use
### Claude Code / Cline
Copy this file to `.agents/skills/unit-test-writer/SKILL.md` in your project root.
Then ask the agent:
- *"Write unit tests for `src/utils/formatCurrency.ts` using the Unit Test Writer skill."*
- *"Use the Unit Test Writer skill to generate Vitest tests for this function."*
Paste the function code into the chat, or reference the file path.
### Cursor
Add the instructions from the "Prompt / Instructions" section below to your `.cursorrules`, or paste them into the Cursor AI pane before asking for tests.
### Codex
Paste your function and the instructions below into the Codex chat. Specify your test framework explicitly (Jest, Vitest, etc.) since Codex does not infer it from the project.
## The Prompt / Instructions for the Agent
When asked to write unit tests, follow these steps:
1. **Read the code.** Understand the function's:
- Inputs (types, shapes, constraints)
- Outputs (return type, side effects)
- Dependencies (external calls, imports that may need mocking)
- Error conditions (what throws, what returns null/undefined)
2. **Identify test cases in this order:**
- **Happy path** — typical valid inputs that produce the expected output
- **Boundary values** — min/max numbers, empty strings, empty arrays, zero
- **Type coercions** — what happens with `null`, `undefined`, `0`, `""`, `false`
- **Error paths** — inputs that should throw or return an error state
- **Async edge cases** (if async) — resolved values, rejected promises, race conditions
- **Mocked dependencies** — external calls (API, DB, filesystem) must be mocked; never make real calls in unit tests
3. **Structure the test file:**
- One `describe` block per function or class
- Nested `describe` blocks for logical groups (e.g., `describe('when user is not logged in', ...)`)
- Test names must read as complete sentences: `it('returns null when input is an empty array')`
- Keep each test focused — one assertion per test when possible, or one concept per test
4. **Mocking rules:**
- Use `jest.mock()` / `vi.mock()` for module-level mocks
- Use `jest.spyOn()` / `vi.spyOn()` for spying on methods without replacing the module
- Always restore mocks in `afterEach` or use `clearMocks: true` in config
- Mock at the boundary — mock the imported module, not internal implementation details
5. **Output format:**
```typescript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; // or jest equivalents
import { functionUnderTest } from '../path/to/module';
// Mock external dependencies
vi.mock('../path/to/dependency', () => ({
someFunction: vi.fn(),
}));
describe('functionUnderTest', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('happy path', () => {
it('returns the expected result for valid input', () => {
// arrange
// act
// assert
});
});
describe('edge cases', () => {
it('returns null when input is an empty array', () => { ... });
it('handles zero correctly', () => { ... });
});
describe('error handling', () => {
it('throws TypeError when input is not a string', () => { ... });
});
});
```
6. **After writing the tests**, list any cases you could not cover and why (e.g., untestable private methods, missing type information).
## Example
**Input to Agent:**
> "Use the Unit Test Writer skill to write Vitest tests for this function:
>
> ```typescript
> export function parsePriceString(price: string): number {
> if (!price || typeof price !== 'string') throw new TypeError('price must be a string');
> const cleaned = price.replace(/[$,\s]/g, '');
> const num = parseFloat(cleaned);
> if (isNaN(num)) throw new RangeError(`Cannot parse price from "${price}"`);
> return num;
> }
> ```"
**Output from Agent:**
```typescript
import { describe, it, expect } from 'vitest';
import { parsePriceString } from '../utils/parsePriceString';
describe('parsePriceString', () => {
describe('happy path', () => {
it('parses a plain number string', () => {
expect(parsePriceString('9.99')).toBe(9.99);
});
it('strips dollar signs', () => {
expect(parsePriceString('$19.99')).toBe(19.99);
});
it('strips commas from large numbers', () => {
expect(parsePriceString('$1,299.00')).toBe(1299);
});
it('strips leading and trailing whitespace', () => {
expect(parsePriceString(' $5.00 ')).toBe(5);
});
});
describe('edge cases', () => {
it('handles zero', () => {
expect(parsePriceString('$0.00')).toBe(0);
});
it('handles a string with only a dollar sign as invalid', () => {
expect(() => parsePriceString('$')).toThrow(RangeError);
});
});
describe('error handling', () => {
it('throws TypeError when price is not a string', () => {
expect(() => parsePriceString(null as any)).toThrow(TypeError);
});
it('throws TypeError when price is undefined', () => {
expect(() => parsePriceString(undefined as any)).toThrow(TypeError);
});
it('throws TypeError when price is an empty string', () => {
expect(() => parsePriceString('')).toThrow(TypeError);
});
it('throws RangeError when string contains no numeric characters', () => {
expect(() => parsePriceString('abc')).toThrow(RangeError);
});
});
});
```
## Notes
- Always specify your test framework. The skill defaults to Vitest syntax, but will adapt to Jest, Mocha, or others on request.
- If the function has many external dependencies, ask the agent to list the mocks it would need before writing the full suite.
- This skill writes the test file only — it does not modify the source file.
- For very large modules, ask for tests one exported function at a time.Related Skills
Unit Test Improver
Reviews existing unit tests for gaps, weak assertions, and missing edge cases, then rewrites them to be more robust.
Technical Blog Post Writer
Writes engaging, accurate technical blog posts targeted at developer audiences.
Social Post Thread Writer
Converts a blog post, idea, or document into an engaging Twitter/X or LinkedIn thread with hooks and CTAs.
SDK Quickstart Writer
Generates a concise, copy-paste-ready quickstart guide for any SDK or library.
README Writer
Generates a professional, comprehensive README.md for any project from its codebase or description.
PR Description Writer
Writes clear, thorough pull request descriptions from a diff or list of changes.
Playwright Test Builder
Generates robust Playwright end-to-end tests for web pages and user flows.
Newsletter Summary Writer
Condenses long articles, threads, or documents into concise, engaging newsletter-ready summaries.
Migration Guide Writer
Writes clear migration guides for library upgrades, breaking API changes, or framework version bumps.
Incident Postmortem Writer
Writes a blameless incident postmortem document from an incident timeline or Slack thread.
Git Commit Writer
Generates conventional commit messages from staged changes or a diff.
Flaky Test Analyzer
Diagnoses why tests pass inconsistently and suggests fixes for timing, ordering, and state isolation issues.