Test Code Quality
Philosophy
Tests are executable spec and documentation for future devs. Clarity beats DRY. Test at the right level.
Code Style
- Follow the
dev-coding-practices skill (functional-first paradigm) for all test code
- DRY is negotiable β repeat yourself if it aids understanding
- A dev a year from now should see context without jumping between many files/helpers
Test Structure
- AAA β Arrange-Act-Assert. Visually separate them. Scannable at a glance.
- One behavior per test β multiple
expect calls fine if same behavior. Don't test unrelated things together.
- Parameterise when similar tests multiply β but keep params readable
Test Naming
Name tests as behavior: rejectsExpiredTokens, not testToken. What broke should be obvious from the name.
Test Data
- Realistic, not
foo/bar. Inline what matters, factory the rest.
- Colocate with shared types/schemas. Auto-generate from schemas where possible. Let types validate your fixtures.
Test Isolation
Test files run in any order, concurrently. Seed DB per file. No cross-file state leakage.
Failure Handling
- Fail loud β message should diagnose without re-running in debug
- Quiet expected failures β mock expected error logging to reduce noise. Keep mocks easy to comment out for debugging.
What to Unit Test
Unit test when it helps validate correctness or aids future maintainability:
- Business logic
- Data transformations
- Code with multiple execution paths
- Pure functions with meaningful logic
When to Skip Unit Tests
If a unit test adds little value:
- Raise up β cover it in an integration test as part of a larger execution path
- Don't test trivial getters, simple pass-throughs, or framework glue
Generally Don't Test Internals
Test observable behavior, not implementation details. Exception: internal tests that aid developing or maintaining complex business logic.
Test Levels
| Level |
When to use |
| Unit |
Isolated logic, transforms, multiple paths |
| Integration |
Multiple units working together, API boundaries |
| E2E |
Happy-path acceptance, user flows |
Push testing to the lowest level that gives confidence. Raise up when unit tests would just duplicate integration coverage.