skills/developer/code-intelligence/test-generation-patterns/SKILL.md
Use this skill when generating tests with AI assistance. Activate when the user wants to create unit tests, integration tests, generate test cases, improve test coverage, write tests for existing code, or set up testing patterns for their project.
npx skillsauth add latestaiagents/agent-skills test-generation-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generate comprehensive tests with AI assistance following 2026 best practices.
┌─────────┐
│ E2E │ Few, slow, high confidence
├─────────┤
│ Integr. │ Some, medium speed
├─────────┤
│ Unit │ Many, fast, isolated
└─────────┘
For any function, test:
Generate comprehensive unit tests for this function:
```[paste function]```
Include tests for:
1. Happy path with typical inputs
2. Edge cases (empty, null, boundary values)
3. Error handling
4. Any state changes or side effects
Use [Vitest/Jest/pytest] with [testing-library if applicable].
Follow AAA pattern (Arrange, Act, Assert).
Code to test:
function parseAmount(input: string): number | null {
if (!input || typeof input !== 'string') return null;
const cleaned = input.replace(/[$,]/g, '').trim();
const num = parseFloat(cleaned);
return isNaN(num) ? null : Math.round(num * 100) / 100;
}
Generated tests:
import { describe, it, expect } from 'vitest';
import { parseAmount } from './parseAmount';
describe('parseAmount', () => {
describe('happy path', () => {
it('parses plain number', () => {
expect(parseAmount('123.45')).toBe(123.45);
});
it('parses number with dollar sign', () => {
expect(parseAmount('$99.99')).toBe(99.99);
});
it('parses number with commas', () => {
expect(parseAmount('1,234.56')).toBe(1234.56);
});
it('parses number with dollar sign and commas', () => {
expect(parseAmount('$1,234.56')).toBe(1234.56);
});
it('rounds to 2 decimal places', () => {
expect(parseAmount('123.456')).toBe(123.46);
});
});
describe('edge cases', () => {
it('handles zero', () => {
expect(parseAmount('0')).toBe(0);
});
it('handles negative numbers', () => {
expect(parseAmount('-50.00')).toBe(-50);
});
it('trims whitespace', () => {
expect(parseAmount(' 123.45 ')).toBe(123.45);
});
it('handles integer input', () => {
expect(parseAmount('100')).toBe(100);
});
});
describe('error cases', () => {
it('returns null for empty string', () => {
expect(parseAmount('')).toBeNull();
});
it('returns null for null input', () => {
expect(parseAmount(null as any)).toBeNull();
});
it('returns null for undefined', () => {
expect(parseAmount(undefined as any)).toBeNull();
});
it('returns null for non-string input', () => {
expect(parseAmount(123 as any)).toBeNull();
});
it('returns null for non-numeric string', () => {
expect(parseAmount('abc')).toBeNull();
});
it('returns null for only symbols', () => {
expect(parseAmount('$,')).toBeNull();
});
});
});
Generate tests for this React component:
```[paste component]```
Test:
1. Renders correctly with required props
2. Renders correctly with optional props
3. User interactions (clicks, inputs)
4. Loading/error states if applicable
5. Accessibility (basic a11y)
Use React Testing Library and Vitest.
Focus on user behavior, not implementation details.
Component:
interface ButtonProps {
label: string;
onClick: () => void;
disabled?: boolean;
loading?: boolean;
}
export function Button({ label, onClick, disabled, loading }: ButtonProps) {
return (
<button
onClick={onClick}
disabled={disabled || loading}
aria-busy={loading}
>
{loading ? 'Loading...' : label}
</button>
);
}
Generated tests:
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, it, expect, vi } from 'vitest';
import { Button } from './Button';
describe('Button', () => {
const defaultProps = {
label: 'Click me',
onClick: vi.fn(),
};
describe('rendering', () => {
it('renders with label', () => {
render(<Button {...defaultProps} />);
expect(screen.getByRole('button', { name: 'Click me' })).toBeInTheDocument();
});
it('renders loading state', () => {
render(<Button {...defaultProps} loading />);
expect(screen.getByRole('button', { name: 'Loading...' })).toBeInTheDocument();
expect(screen.getByRole('button')).toHaveAttribute('aria-busy', 'true');
});
it('renders disabled state', () => {
render(<Button {...defaultProps} disabled />);
expect(screen.getByRole('button')).toBeDisabled();
});
});
describe('interactions', () => {
it('calls onClick when clicked', async () => {
const onClick = vi.fn();
render(<Button {...defaultProps} onClick={onClick} />);
await userEvent.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalledTimes(1);
});
it('does not call onClick when disabled', async () => {
const onClick = vi.fn();
render(<Button {...defaultProps} onClick={onClick} disabled />);
await userEvent.click(screen.getByRole('button'));
expect(onClick).not.toHaveBeenCalled();
});
it('does not call onClick when loading', async () => {
const onClick = vi.fn();
render(<Button {...defaultProps} onClick={onClick} loading />);
await userEvent.click(screen.getByRole('button'));
expect(onClick).not.toHaveBeenCalled();
});
});
describe('accessibility', () => {
it('is focusable', async () => {
render(<Button {...defaultProps} />);
await userEvent.tab();
expect(screen.getByRole('button')).toHaveFocus();
});
it('can be activated with Enter key', async () => {
const onClick = vi.fn();
render(<Button {...defaultProps} onClick={onClick} />);
await userEvent.tab();
await userEvent.keyboard('{Enter}');
expect(onClick).toHaveBeenCalled();
});
});
});
Generate integration tests for this API endpoint:
```[paste route handler]```
Test:
1. Successful requests with valid data
2. Validation errors (400)
3. Authentication/authorization (401/403)
4. Not found cases (404)
5. Server errors (500)
Use [supertest/axios] with proper mocking.
| Area | Target | Priority | |------|--------|----------| | Business logic | 90%+ | High | | Utilities | 100% | High | | API routes | 80%+ | High | | Components | 70%+ | Medium | | Integrations | 60%+ | Medium |
Here's my current code and test file. Identify untested paths
and generate tests to cover them:
Code:
```[paste code]```
Existing tests:
```[paste tests]```
Coverage report shows these lines uncovered: [lines]
Generate test fixtures for this type:
```typescript
interface Order {
id: string;
customerId: string;
items: OrderItem[];
status: 'pending' | 'processing' | 'shipped' | 'delivered';
total: number;
createdAt: Date;
}
Create:
## Common Testing Patterns
### Factory Pattern
```typescript
function createOrder(overrides: Partial<Order> = {}): Order {
return {
id: 'order-123',
customerId: 'customer-456',
items: [{ productId: 'prod-1', quantity: 1, price: 10 }],
status: 'pending',
total: 10,
createdAt: new Date('2024-01-01'),
...overrides,
};
}
// Usage in tests
const pendingOrder = createOrder();
const shippedOrder = createOrder({ status: 'shipped' });
const emptyOrder = createOrder({ items: [], total: 0 });
// Service mock
vi.mock('./userService', () => ({
getUser: vi.fn().mockResolvedValue({ id: '1', name: 'John' }),
}));
// Spy on method
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
// Mock module partially
vi.mock('./utils', async () => {
const actual = await vi.importActual('./utils');
return {
...actual,
formatDate: vi.fn().mockReturnValue('2024-01-01'),
};
});
development
Test skills for correct activation, content quality, and regression — both automated checks (frontmatter validity, lint) and manual verification (query-suite activation testing). Covers CI integration and how to catch skill regressions before users do. Use this skill when adding skills to a repo, setting up CI for a skill library, or debugging "the skill exists but doesn't work". Activate when: test skills, validate skills, skill CI, skill linting, skill activation test, skill regression.
documentation
Write the YAML frontmatter for a SKILL.md file so it activates reliably — name, description, and activation keywords that the model matches against. Covers length, tone, and the most common frontmatter mistakes. Use this skill when authoring a new skill, fixing a skill that isn't auto-activating, or reviewing skills for publication. Activate when: SKILL.md frontmatter, skill description, skill activation, skill YAML, write a skill, author a skill.
development
Design skills that fire at the right moment — neither over-eager (noise) nor under-eager (silent). Covers activation specificity, trigger phrases, disambiguation between overlapping skills, and debugging activation. Use this skill when multiple skills could fire on the same query, a skill never fires, or a skill fires too often. Activate when: skill won't activate, skill over-activates, overlapping skills, skill triggers, skill selection, skill disambiguation.
development
Structure SKILL.md content so the model reads just enough — concise summary up front, progressively deeper detail, examples on demand. Covers section ordering, length budgets, when to split into multiple skills. Use this skill when writing or refactoring a skill body, one skill has grown too long, or a skill is wordy but not useful. Activate when: SKILL.md structure, skill content, skill too long, split skill, progressive disclosure, skill body.