From latestaiagents
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 claudepluginhub latestaiagents/agent-skills --plugin skills-authoringThis skill uses the workspace's default tool permissions.
Generate comprehensive tests with AI assistance following 2026 best practices.
Generates unit, integration, component, and e2e test suites with mocking strategies, edge case coverage, descriptive naming, and CI integration patterns. Activates on 'write tests', 'unit tests', 'mocking' requests.
Designs testing strategies with checklists, pyramid, framework recommendations, and AAA templates for unit, integration, and E2E tests in JS/TS, Python, and Go codebases.
Provides testing pyramid, unit patterns (AAA, isolation, parameterized, edge cases), and React Testing Library for component tests. Use when writing tests or setting up testing infrastructure.
Share bugs, ideas, or general feedback.
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'),
};
});