write-tests
Generates comprehensive tests for a given file, function, class, or module. Covers unit tests, integration tests, edge cases, error paths, and mocking. Use when the user says "write tests", "add tests", "test this", "create tests for", "generate test cases", "cover this with tests", or "improve test coverage".
What this skill does
# Write Tests Skill
When writing tests, follow this structured process. Good tests verify behavior, catch regressions, and serve as living documentation.
## 1. Discovery — Understand What to Test
Before writing any tests, analyze the code:
### Detect Testing Setup
```bash
# Detect framework and config
cat package.json 2>/dev/null | grep -E "jest|vitest|mocha|ava|playwright|cypress|testing-library"
cat jest.config.* vitest.config.* 2>/dev/null | head -30
cat pyproject.toml 2>/dev/null | grep -A 20 "\[tool.pytest"
cat pytest.ini conftest.py 2>/dev/null | head -20
cat .rspec spec/spec_helper.rb 2>/dev/null | head -20
cat phpunit.xml 2>/dev/null | head -20
# Find existing test examples to match patterns
find . -name "*.test.*" -o -name "*.spec.*" -o -name "test_*" -o -name "*_test.*" | head -10
# Read an existing test file to understand conventions
# (pick the most recent or most relevant one)
```
### Analyze the Code Under Test
```bash
# Read the file to understand its exports and dependencies
cat [target-file]
# Find what it imports (these might need mocking)
grep -E "^import|^from|require\(" [target-file]
# Find what exports it provides (these are what we test)
grep -E "^export|module\.exports" [target-file]
# Find related types/interfaces
grep -E "interface |type |class " [target-file]
```
### Identify Test Cases
For each function/method/class, identify:
1. **Happy path** — normal successful operation
2. **Edge cases** — boundary values, empty inputs, limits
3. **Error cases** — invalid inputs, failures, exceptions
4. **Integration points** — database, API, file system calls
5. **State transitions** — before/after state changes
6. **Concurrency** — race conditions, parallel execution
7. **Security** — malicious inputs, injection attempts
## 2. Test Structure Principles
### Arrange-Act-Assert (AAA)
```
// Arrange — set up the test data and conditions
// Act — execute the code under test
// Assert — verify the results
```
### Test Naming
Use descriptive names that explain the scenario:
```
// Pattern: [unit] [scenario] [expected result]
// ✅ GOOD
"createUser returns user with generated UUID when valid email provided"
"createUser throws ValidationError when email is empty string"
"createUser hashes password with bcrypt before saving"
// 🔴 BAD
"createUser works"
"test 1"
"should work correctly"
```
### Test Organization
```
describe('[Module/Class/Function]', () => {
describe('[method or scenario group]', () => {
it('[specific behavior]', () => { ... });
});
});
```
### What Makes a Good Test
- **Independent** — no test depends on another test's state
- **Deterministic** — same result every time (no random, no timing)
- **Fast** — unit tests < 100ms each
- **Readable** — a test is documentation; anyone should understand it
- **Focused** — one assertion concept per test (can have multiple expect statements)
- **Realistic** — test data resembles real data, not `"test"` and `123`
## 3. Stack-Specific Test Generation
### TypeScript / JavaScript — Jest
```typescript
import { describe, it, expect, jest, beforeEach, afterEach } from '@jest/globals';
import { OrderService } from '../services/orderService';
import { OrderRepository } from '../db/repositories/orderRepository';
import { PaymentService } from '../lib/paymentService';
import { NotificationService } from '../lib/notificationService';
import type { CreateOrderInput, Order } from '../models/order';
// Mock dependencies
jest.mock('../db/repositories/orderRepository');
jest.mock('../lib/paymentService');
jest.mock('../lib/notificationService');
describe('OrderService', () => {
let orderService: OrderService;
let mockOrderRepo: jest.Mocked<OrderRepository>;
let mockPaymentService: jest.Mocked<PaymentService>;
let mockNotificationService: jest.Mocked<NotificationService>;
// --- Setup & Teardown ---
beforeEach(() => {
mockOrderRepo = new OrderRepository() as jest.Mocked<OrderRepository>;
mockPaymentService = new PaymentService() as jest.Mocked<PaymentService>;
mockNotificationService = new NotificationService() as jest.Mocked<NotificationService>;
orderService = new OrderService(mockOrderRepo, mockPaymentService, mockNotificationService);
});
afterEach(() => {
jest.restoreAllMocks();
});
// --- Test Data Factories ---
const createValidOrderInput = (overrides?: Partial<CreateOrderInput>): CreateOrderInput => ({
userId: 'user-abc-123',
items: [
{ productId: 'prod-001', quantity: 2, priceInCents: 2999 },
{ productId: 'prod-002', quantity: 1, priceInCents: 4999 },
],
shippingAddress: {
street: '123 Main St',
city: 'Springfield',
state: 'IL',
zip: '62701',
country: 'US',
},
...overrides,
});
const createMockOrder = (overrides?: Partial<Order>): Order => ({
id: 'order-xyz-789',
userId: 'user-abc-123',
status: 'pending',
totalInCents: 10997,
items: [],
createdAt: new Date('2026-01-15T10:00:00Z'),
updatedAt: new Date('2026-01-15T10:00:00Z'),
...overrides,
});
// --- Tests ---
describe('createOrder', () => {
// Happy Path
describe('when given valid input', () => {
it('creates an order with correct total calculated from items', async () => {
const input = createValidOrderInput();
mockOrderRepo.create.mockResolvedValue(createMockOrder({ totalInCents: 10997 }));
mockPaymentService.authorize.mockResolvedValue({ transactionId: 'txn-001' });
const result = await orderService.createOrder(input);
expect(mockOrderRepo.create).toHaveBeenCalledWith(
expect.objectContaining({
userId: 'user-abc-123',
totalInCents: 10997, // (2999 * 2) + (4999 * 1)
})
);
expect(result.totalInCents).toBe(10997);
});
it('authorizes payment before saving the order', async () => {
const input = createValidOrderInput();
mockOrderRepo.create.mockResolvedValue(createMockOrder());
mockPaymentService.authorize.mockResolvedValue({ transactionId: 'txn-001' });
await orderService.createOrder(input);
// Verify payment authorization was called before order creation
const paymentCallOrder = mockPaymentService.authorize.mock.invocationCallOrder[0];
const repoCallOrder = mockOrderRepo.create.mock.invocationCallOrder[0];
expect(paymentCallOrder).toBeLessThan(repoCallOrder);
});
it('sends order confirmation notification', async () => {
const input = createValidOrderInput();
mockOrderRepo.create.mockResolvedValue(createMockOrder());
mockPaymentService.authorize.mockResolvedValue({ transactionId: 'txn-001' });
await orderService.createOrder(input);
expect(mockNotificationService.sendOrderConfirmation).toHaveBeenCalledWith(
expect.objectContaining({
userId: 'user-abc-123',
orderId: 'order-xyz-789',
})
);
});
});
// Edge Cases
describe('edge cases', () => {
it('handles single item order', async () => {
const input = createValidOrderInput({
items: [{ productId: 'prod-001', quantity: 1, priceInCents: 999 }],
});
mockOrderRepo.create.mockResolvedValue(createMockOrder({ totalInCents: 999 }));
mockPaymentService.authorize.mockResolvedValue({ transactionId: 'txn-001' });
const result = await orderService.createOrder(input);
expect(result.totalInCents).toBe(999);
});
it('handles maximum quantity per item', async () => {
const input = createValidOrderInput({
items: [{ productId: 'prod-001', quantity: 99, priceInCents: 100 }],
});
mockOrderRepo.create.mockResolvedValue(createMockOrder({ totalInCents: 9900 }));
mockPaymentService.authorize.mockResolvedValue({ transactionId: 'txn-001' });
const result = await orderService.createOrder(input);
Related in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.