writing-tests
Writing Tests
Core principle: Test user-observable behavior with real dependencies. Tests should survive refactoring.
"The more your tests resemble the way your software is used, the more confidence they can give you." — Kent C. Dodds
Why this matters: Tests exist to give you confidence. The Testing Trophy prioritizes integration tests because they test real behavior across real modules — giving maximum confidence per test written. Unit tests in isolation often just test mocks, not your actual system.
Testing Trophy Model
| Priority | Type | When |
|---|---|---|
| 1st | Integration | Default - multiple units with real dependencies |
| 2nd | E2E | Complete user workflows |
| 3rd | Unit | Pure functions only (no dependencies) |
Mocking Guidelines
Default: Don't mock. Use real dependencies.
Only mock:
- External HTTP/API calls
- Time/randomness
- Third-party services (payments, email)
Never mock:
- Internal modules
- Database queries (use test DB)
- Business logic
- Your own code calling your own code
Before mocking, ask: "What side effects does this have? Does my test need those?" If unsure, run with real implementation first, then add minimal mocking only where needed.
Test Type Decision
Complete user workflow? → E2E test
Pure function (no side effects)? → Unit test
Everything else → Integration test
Assertion Strategy
| Context | Assert On | Avoid |
|---|---|---|
| UI | Visible text, roles | CSS classes, internal state |
| API | Response body, status | Internal DB state |
| Library | Return values | Private methods |
Anti-Patterns
| Pattern | Fix |
|---|---|
| Testing mock calls | Test actual outcome |
| Test-only methods in production | Move to test utilities |
sleep(500) |
Use condition-based waiting |
| Asserting on internal state | Assert on observable output |
| Incomplete mocks | Mirror real API completely |
Quality Checklist
- Happy path covered
- Error conditions handled
- Real dependencies used (minimal mocking)
- Tests survive refactoring
- Test names describe behavior
Language-Specific Patterns
- JavaScript/Typescript/React: See references/typescript-react.md
- Python: See references/python.md
- Go: See references/go.md
For flaky tests with timing issues, use Skill(ce:condition-based-waiting).
Remember: Behavior over implementation. Real over mocked. Outputs over internals.
More from rileyhilliard/claude-essentials
design
Enforces precise, minimal design for dashboards and admin interfaces. Use when building SaaS UIs, data-heavy interfaces, or any product needing Jony Ive-level craft.
18writer
Writing style and tone guide for human-sounding content. Use when writing documentation, READMEs, commit messages, PR descriptions, blog posts, or any user-facing content.
16strategy-writer
Produces executive-quality strategic documents in The Economist/HBR style. Use when writing strategy memos, market analysis, business cases, customer research reports, or any document for Product, Design, and Business leaders. Customer-led, evidence-based, narrative-driven.
13executing-plans
Executes implementation plans with smart task grouping. Groups related tasks to share context, parallelizes across independent subsystems.
12refactoring-code
Improves code structure while preserving behavior through test verification. Use when cleaning up code, reducing duplication, simplifying complexity, or reorganizing modules.
12handling-errors
Prevents silent failures and context loss in error handling. Use when writing try-catch blocks, designing error propagation, reviewing catch blocks, or implementing Result patterns.
12