| name | testing |
| description | Software testing expertise for writing effective tests. Use when writing tests, reviewing test quality, designing test suites, debugging test failures, or implementing TDD. Covers xUnit patterns, test case selection, mocks/fixtures, parametrization, testing stateful systems, BDD, golden/snapshot testing, and LLM output evaluation. |
Testing Skill
Core principle: Testing is risk management. Tests catch mistakes before production. Code never works the first time, and working code won't stay working without tests.
Test Case Selection (The Map Analogy)
Think of your code's behavior as a map. Select test cases systematically:
- Start simple - Basic happy path cases first
- Cover every subdivision - Each distinct behavior region needs coverage
- Find surprising subdivisions - Edge cases that aren't obvious (embassies on a map)
- Hug borders tightly - Test boundary conditions precisely
- Look for multipoints - Where multiple boundaries meet (0, 1, -1 for ranges)
Example: Testing range(start, stop, step)
expect(range(3)).toEqual([0, 1, 2]);
expect(range(5, 0, -1)).toEqual([5, 4, 3, 2, 1]);
expect(range(3, 1)).toEqual([]);
expect(range(1, 5, 2)).toEqual([1, 3]);
expect(range(1, 4, 2)).toEqual([1, 3]);
expect(range(1, 3, 2)).toEqual([1]);
expect(range(0, 1, 1)).toEqual([0]);
expect(() => range(0, 1, 0)).toThrow();
Test Structure: Given-When-Then
test('finalize order empties shopping cart', () => {
const user = createAccount({ name: 'Adam' });
addToShoppingCart(user, pizza, { quantity: 1 });
finalizeOrder(user, { creditCard: 'XXXX-...' });
expect(getShoppingCart(user)).toBeUndefined();
});
DRY vs DAMP
- DAMP (Descriptive And Meaningful Phrase): Each test readable in isolation, some repetition OK
- DRY: Share setup code to reduce duplication
Guideline: With 100 similar tests, build a test harness. With 5 tests, copy-paste is fine.
Quick Reference
Anti-patterns
- Tests that depend on execution order
- Tests that share mutable state
- Over-mocking (mock the DB? Usually no. Mock Stripe API? Yes.)
- Testing implementation details instead of behavior
- 100% coverage as a goal (coverage shows what you DIDN'T test, not quality)
Things Hard to Test
- UI: Automated visual tests rarely worth the effort
- Nondeterministic code: Question why you're writing it
- Distributed systems: Read Jepsen posts, good luck