| name | testing |
| description | Write and run tests. Tests are REQUIRED. All must pass. |
/testing [level]
Write and RUN tests. Tests are REQUIRED, not optional.
No arguments? Describe this skill and stop. Do not execute.
First: Activate Workflow
mkdir -p .claude && echo '{"skill":"test","started":"'$(date -Iseconds)'"}' > .claude/active-workflow.json
Craft Standards (MANDATORY)
Write tests a master craftsperson would be proud of.
Tests must look like they were written by a skilled human engineer, not generated by AI.
AI Antipatterns in Tests to REJECT
- Testing implementation details instead of behavior
- Excessive mocking that makes tests brittle
- Mocking the system under test — if you're testing storage and you mock storage, you're testing nothing. Mocks replace dependencies, never the thing being tested.
- Tests that pass even when code is broken (useless assertions)
- Copy-paste test code (extract helpers)
- Testing obvious things (constructors, getters)
- Overly verbose arrange/act/assert with boilerplate
Human Craft in Tests
- Tests that document intended behavior
- Clear test names that read as specifications
- Focused tests - one concept per test
- Tests that fail meaningfully when code breaks
- Minimal setup - only what's needed
- Tests others can read and understand
Test: Would you trust this test suite to catch real bugs? If not, improve it.
⚠️ STRICT REQUIREMENTS - NO JUDGMENT CALLS
You MUST write and run tests. Not "consider testing" - WRITE TESTS.
- MINIMUM COVERAGE - At least one test per public function
- HAPPY PATH - Test the expected behavior works
- ERROR CASES - Test that errors are handled correctly
- EDGE CASES - Test boundary conditions
- NON-HAPPY-PATH - Test failure and recovery scenarios (see below)
- MUST RUN - Execute tests with npm test/vitest/jest and verify they pass
- ALL MUST PASS - Zero failing tests allowed
Non-Happy-Path Categories (MANDATORY)
For each category that applies to the target code, write at least one test:
- Corrupted data recovery — What happens when persisted files contain
invalid JSON, truncated data, wrong version, or zero bytes? Test that the
code fails gracefully with a clear error, not a stack trace or silent corruption.
- Lock contention — If the code uses file locks or mutexes, test what
happens when the lock is already held (timeout, retry, clear error message).
- Interrupted writes — If the code writes files, test what happens when
the write is interrupted (temp file left behind, partial write). Verify
cleanup occurs.
- Symlink / path escape — If the code validates paths, test that symlinks
pointing outside the allowed directory are rejected.
- Resource exhaustion — If the code reads unbounded input (stdin, files),
test that size limits are enforced.
Skip categories that genuinely don't apply (e.g., no file I/O means no
corrupted data test). But document which categories you skipped and why.
FORBIDDEN (Phase will FAIL if detected):
- Saying "testing would be beneficial" without writing tests
- Writing tests that don't run
- Leaving failing tests
- Skipping error case testing
- Writing trivial tests that don't verify behavior
- Not running the tests
- Mocking the module under test (mock dependencies, not the subject)
Levels
/testing unit - Unit tests only
/testing integration - Integration tests only
/testing e2e - E2E tests only
/testing all or /testing - All appropriate levels
Process
Step 0: Load Expert Guidance
Before starting, read these canon skills and apply their principles throughout:
Always load:
canon/testing/test-doubles/SKILL.md
canon/testing/test-strategy/SKILL.md
Auto-detect domain canon (check files, load matches):
| Check | If found, also read |
|---|
*.ts or *.js files in target | canon/javascript/typescript/SUMMARY.md, canon/javascript/js-safety/SUMMARY.md, canon/javascript/js-perf/SUMMARY.md, canon/javascript/js-internals/SUMMARY.md, canon/javascript/functional/SUMMARY.md |
angular.json in project root | canon/angular/angular-arch/SUMMARY.md, canon/angular/angular-core/SUMMARY.md, canon/angular/angular-perf/SUMMARY.md, canon/angular/rxjs/SUMMARY.md |
package.json contains "react" | canon/javascript/react-state/SUMMARY.md, canon/javascript/react-test/SUMMARY.md, canon/javascript/reactivity/SUMMARY.md |
pom.xml or build.gradle in project | canon/java/SUMMARY.md |
*.py files in target | canon/python/python-advanced/SUMMARY.md, canon/python/python-idioms/SUMMARY.md, canon/python/python-patterns/SUMMARY.md, canon/python/python-protocols/SUMMARY.md |
*.cs files or *.csproj in project | canon/csharp/csharp-depth/SUMMARY.md, canon/csharp/type-systems/SUMMARY.md, canon/csharp/async/SUMMARY.md |
.tsx, .jsx, or HTML template files | canon/ui-ux/components/SUMMARY.md, canon/ui-ux/usability/SUMMARY.md, canon/ui-ux/tokens/SUMMARY.md |
| Auth, tokens, secrets, encryption | canon/security/security-mindset/SUMMARY.md, canon/security/owasp/SUMMARY.md, canon/security/web-security/SUMMARY.md |
If a skill file doesn't exist (not installed in this project), skip it and continue.
List loaded experts in EXPERTS_LOADED. In EXPERT_DECISIONS, show each specific test decision an expert drove.
Step 1: Find Code
- Find Code - Identify what needs testing
- Write Tests - Create test files with real assertions
- Mock Audit - Before running, review every mock/stub/spy in your tests:
- What module does this mock replace?
- Is that module the thing being tested or a dependency of the thing being tested?
- If you mocked the thing being tested, delete the mock and test the real implementation
- Example: testing
keychain.ts → mock crypto.ts (dependency) ✓, mock storage.ts I/O (dependency) ✓, mock keychain.ts itself ✗
- For I/O-heavy code: use temp directories and real filesystem operations where possible. Integration tests that touch real I/O catch bugs that mocked tests hide.
- Run Tests - Execute and verify they pass
- Report - Document what was tested
REQUIRED Output Format
## Tests: [target]
TESTS_WRITTEN:
- src/__tests__/user.test.ts: [test descriptions]
- src/__tests__/auth.test.ts: [test descriptions]
TESTS_RUN: yes (MANDATORY)
TESTS_PASSED: N
TESTS_FAILED: 0 (must be zero)
TEST_COUNT: N
MOCK_AUDIT:
- [module under test]: mocks [dependency] ✓ | mocks self ✗ (FIXED)
- [module under test]: no mocks, tests real implementation ✓
COVERAGE:
- createUser: tested (happy path, validation error, duplicate email)
- validateToken: tested (valid, expired, malformed)
EXPERTS_LOADED: [list of skill names actually read]
EXPERT_DECISIONS:
- [expert-skill]: [specific test decision it drove]
TESTING_COMPLETE
Validation (Phase will FAIL if violated)
- TEST_COUNT: 0 (no tests written)
- TESTS_RUN: no (tests not executed)
- TESTS_FAILED > 0 (failing tests)
🛑 MANDATORY STOP
After testing:
- DO NOT proceed to next phase
- DO NOT continue with "let me also..."
Your turn ends here. Output TESTING_COMPLETE and STOP.