distributions/direct/example/testing-patterns/SKILL.md
Write effective tests across the stack—unit, integration, E2E, and visual regression. Covers testing philosophy, framework selection, mocking strategies, and CI integration. Triggers on testing, test coverage, TDD, or quality assurance requests.
npx skillsauth add a-organvm/a-i--skills testing-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.
Build confidence through strategic testing.
╱╲
╱ ╲ E2E (few)
╱────╲
╱ ╲ Integration (more)
╱────────╲
╱ ╲ Unit (many, fast)
╱────────────╲
╱ Static ╲ TypeScript, ESLint
╱────────────────╲
| Test Type | What | Why | |-----------|------|-----| | Static | Types, lint rules | Catch errors at write-time | | Unit | Pure functions, utils | Fast, precise feedback | | Integration | Component + dependencies | Test contracts | | E2E | User flows | Confidence in real usage |
describe('calculateTotal', () => {
it('should apply discount to subtotal', () => {
// Arrange
const items = [{ price: 100 }, { price: 50 }];
const discount = 0.1;
// Act
const result = calculateTotal(items, discount);
// Assert
expect(result).toBe(135);
});
});
// Pattern: should [expected behavior] when [condition]
it('should return empty array when input is null')
it('should throw error when user is not authenticated')
it('should apply discount when coupon is valid')
// utils/format.ts
export function formatCurrency(cents: number): string {
return `$${(cents / 100).toFixed(2)}`;
}
// utils/format.test.ts
describe('formatCurrency', () => {
it('should format cents to dollar string', () => {
expect(formatCurrency(1000)).toBe('$10.00');
expect(formatCurrency(1)).toBe('$0.01');
expect(formatCurrency(0)).toBe('$0.00');
});
it('should handle negative values', () => {
expect(formatCurrency(-500)).toBe('$-5.00');
});
});
"The more your tests resemble the way your software is used, the more confidence they can give you."
import { render, screen, fireEvent } from '@testing-library/react';
import { Counter } from './Counter';
describe('Counter', () => {
it('should increment count when button clicked', async () => {
render(<Counter initialCount={0} />);
const button = screen.getByRole('button', { name: /increment/i });
await fireEvent.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
});
Use queries in this order (most to least preferred):
getByRole - Accessible to everyonegetByLabelText - Form fieldsgetByPlaceholderText - If no labelgetByText - Non-interactive contentgetByTestId - Last resortimport { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
it('should load data after button click', async () => {
const user = userEvent.setup();
render(<DataLoader />);
await user.click(screen.getByRole('button', { name: /load/i }));
// Wait for async content
await waitFor(() => {
expect(screen.getByText('Data loaded')).toBeInTheDocument();
});
});
// Mock a module
vi.mock('./api', () => ({
fetchUser: vi.fn(() => Promise.resolve({ name: 'Test User' })),
}));
// Mock a hook
vi.mock('./useAuth', () => ({
useAuth: () => ({ user: { id: '1' }, isLoading: false }),
}));
// Mock fetch
global.fetch = vi.fn(() =>
Promise.resolve({
json: () => Promise.resolve({ data: 'test' }),
})
);
import { createMocks } from 'node-mocks-http';
import handler from './api/posts';
describe('/api/posts', () => {
it('should return posts list', async () => {
const { req, res } = createMocks({
method: 'GET',
});
await handler(req, res);
expect(res._getStatusCode()).toBe(200);
expect(JSON.parse(res._getData())).toHaveLength(3);
});
});
import { db } from '@/lib/db';
describe('User service', () => {
beforeEach(async () => {
await db.user.deleteMany(); // Clean state
});
afterAll(async () => {
await db.$disconnect();
});
it('should create user with valid data', async () => {
const user = await createUser({
email: '[email protected]',
name: 'Test User'
});
expect(user.id).toBeDefined();
expect(user.email).toBe('[email protected]');
});
});
// e2e/auth.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Authentication', () => {
test('should allow user to sign in', async ({ page }) => {
await page.goto('/login');
await page.fill('[name="email"]', '[email protected]');
await page.fill('[name="password"]', 'password123');
await page.click('button[type="submit"]');
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('h1')).toContainText('Welcome');
});
});
// e2e/pages/login.page.ts
export class LoginPage {
constructor(private page: Page) {}
async goto() {
await this.page.goto('/login');
}
async login(email: string, password: string) { <!-- allow-secret -->
await this.page.fill('[name="email"]', email);
await this.page.fill('[name="password"]', password);
await this.page.click('button[type="submit"]');
}
}
// e2e/auth.spec.ts
test('should login successfully', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('[email protected]', 'password');
await expect(page).toHaveURL('/dashboard');
});
test('homepage should match snapshot', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveScreenshot('homepage.png');
});
| Mock | When | |------|------| | External APIs | Always in unit/integration | | Database | Sometimes (test containers vs mocks) | | Time/Date | When testing time-dependent logic | | Randomness | When testing deterministic output | | Network | Always in unit tests |
// mocks/handlers.ts
import { rest } from 'msw';
export const handlers = [
rest.get('/api/users', (req, res, ctx) => {
return res(
ctx.json([
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
])
);
}),
rest.post('/api/users', async (req, res, ctx) => {
const body = await req.json();
return res(ctx.status(201), ctx.json({ id: 3, ...body }));
}),
];
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
globals: true,
setupFiles: ['./test/setup.ts'],
coverage: {
reporter: ['text', 'html'],
exclude: ['node_modules/', 'test/'],
},
},
});
// test/setup.ts
import '@testing-library/jest-dom';
import { server } from './mocks/server';
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
| Type | Target | Notes | |------|--------|-------| | Statements | 70-80% | Don't chase 100% | | Branches | 70-80% | Test important paths | | Functions | 80%+ | All public APIs | | Lines | 70-80% | Balance with velocity |
# .github/workflows/test.yml
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run test:coverage
- uses: codecov/codecov-action@v3
with:
files: ./coverage/lcov.info
references/vitest-patterns.md - Vitest specific patternsreferences/playwright-patterns.md - E2E testing patternsreferences/mock-examples.md - Mocking recipesdevelopment
Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks
development
Conducts a full automated autopsy of the current workspace directory to map files, identifies structural issues, proposes a restructuring plan (the signal), and establishes unified governance using templates. Use this skill when a user asks to map, restructure, reorganize, or apply new governance to an existing messy repository.
testing
Design engaging workshops, conference talks, and educational presentations. Covers learning objectives, activity design, slide craft, and facilitation techniques. Triggers on workshop design, presentation prep, talk structure, or training session requests.
development
Designs reliable webhook systems with proper delivery guarantees, retry logic, signature verification, and idempotent processing for event-driven integrations.