.claude/skills/tdd/SKILL.md
Test-Driven Development workflow. Use for ALL code changes - features, bug fixes, refactoring. TDD is non-negotiable.
npx skillsauth add jscriptcoder/jshack.me tddInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
TDD is the fundamental practice. Every line of production code must be written in response to a failing test.
For how to write good tests, load the testing skill. This skill focuses on the TDD workflow/process.
mutation-testing skill against the changed codeCommit history should show clear RED → GREEN → MUTATE → KILL MUTANTS → REFACTOR progression.
Ideal progression:
commit abc123: test: add failing test for filesystem traversal check
commit def456: feat: implement traversal permission checking to pass test
commit ghi789: test: strengthen boundary tests (mutation testing)
commit jkl012: refactor: extract permission helpers for clarity
TDD evidence may not be linearly visible in commits in these cases:
1. Multi-Session Work
2. Context Continuation
3. Refactoring Commits
When exception applies, document in PR description:
## TDD Evidence
RED phase: commit c925187 (added failing tests for NAT resolution)
GREEN phase: commits 5e0055b, 9a246d0 (implementation + bug fixes)
MUTATE + KILL MUTANTS: commit 7b8c9d0 (strengthened boundary tests)
REFACTOR: commit 11dbd1a (test isolation improvements)
Test Evidence:
✅ 4/4 tests passing (7.7s with 4 workers)
Important: Exception is for EVIDENCE presentation, not TDD practice. TDD process must still be followed - these are cases where commit history doesn't perfectly reflect the process that was actually followed.
Always run coverage yourself before approving PRs.
Before approving any PR claiming "100% coverage":
Check out the branch
git checkout feature-branch
Run coverage verification:
npm run test:coverage
Verify ALL metrics hit 100%:
Check that tests are behavior-driven (not testing implementation details)
For anti-patterns that create fake coverage (coverage theater), see the testing skill.
Look for the "All files" line in coverage summary:
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
fileSystemUtils.ts | 100 | 100 | 100 | 100 |
fileSystemFactory.ts | 100 | 100 | 100 | 100 |
enrichment.ts | 100 | 100 | 100 | 100 |
✅ This is 100% coverage - all four metrics at 100%.
Watch for these signs of incomplete coverage:
❌ PR claims "100% coverage" but you haven't verified
❌ Coverage summary shows <100% on any metric
All files | 97.11 | 93.97 | 81.81 | 97.11 |
❌ "Uncovered Line #s" column shows line numbers
enrichment.ts | 95.23 | 100 | 60 | 95.23 | 45-48, 52-55
❌ Coverage gaps without explicit exception documentation
"What business behavior am I not testing?"
NOT "What line am I missing?"
Add tests for behavior, and coverage follows naturally.
No exceptions without explicit approval and documentation.
If 100% coverage cannot be achieved:
Step 1: Document in package README
Explain:
Step 2: Get explicit approval
From project maintainer or team lead
Step 3: Document in CLAUDE.md
Under "Test Coverage: 100% Required" section, list the exception
Example Exception:
## Current Exceptions
- **React Terminal Component**: 86% function coverage
- Documented in `/src/components/Terminal/README.md`
- Missing coverage from async command streaming (tested in E2E layer)
- Approved: 2024-11-15
The burden of proof is on the requester. 100% is the default expectation.
npm test)# 1. Write failing test
it('rejects traversal for guest through root-only directory', () => {
const fs = mkDir('root', { secret: mkDir('secret', {}, 'root', false) });
const result = checkTraversal(fs, '/secret/data.txt', 'guest');
expect(result.allowed).toBe(false);
}); # ❌ Test fails (no implementation)
# 2. Implement minimum code
if (!dir.permissions.execute.includes(userType)) {
return { allowed: false, reason: `${path}: Permission denied` };
} # ✅ Test passes
# 3. Run mutation testing to verify test strength
# 4. Kill surviving mutants (ask human when ambiguous)
# 5. Refactor if needed (extract helper, improve naming)
# 6. Commit
git add .
git commit -m "feat: enforce execute permission on directory traversal"
Use conventional commits format:
feat: add SNMP firewall override for gateway machines
fix: correct NAT resolution for inner subnet gateways
refactor: extract permission checking into utility functions
test: add edge cases for filesystem traversal
docs: update architecture documentation
Format:
feat: - New featurefix: - Bug fixrefactor: - Code change that neither fixes bug nor adds featuretest: - Adding or updating testsdocs: - Documentation changesBefore submitting PR:
Example PR Description:
## Summary
Adds filesystem traversal permission checking with execute-bit enforcement on directories.
## Behavior Changes
- Directory traversal now requires execute permission on each path segment
- Root user bypasses all permission checks
- Guest users can only traverse world-readable directories
## Test Evidence
✅ 12/12 tests passing
✅ 100% coverage verified (see coverage report)
## TDD Evidence
RED: commit 4a3b2c1 (failing tests for traversal checking)
GREEN: commit 5d4e3f2 (implementation)
REFACTOR: commit 6e5f4a3 (extract permission resolution logic)
After mutation testing confirms test strength, classify any issues:
| Priority | Action | Examples | | -------- | ------------ | --------------------------------------------------- | | Critical | Fix now | Mutations, knowledge duplication, >3 levels nesting | | High | This session | Magic numbers, unclear names, >30 line functions | | Nice | Later | Minor naming, single-use helpers | | Skip | Don't change | Already clean code |
For detailed refactoring methodology, load the refactoring skill.
let/beforeEach for test dataFor detailed testing anti-patterns, load the testing skill.
Before marking work complete:
let/beforeEach)development
TypeScript strict mode patterns including schema-first development, branded types, type vs interface guidance, and tsconfig strict flags. Use when writing TypeScript code, defining types or schemas, or reviewing type safety. For immutability and pure function patterns, see the functional skill.
development
Testing patterns for behavior-driven tests. Use when writing tests, creating test factories, structuring test files, or deciding what to test. Do NOT use for UI-specific testing (see front-end-testing or react-testing skills).
testing
Evaluates test quality using Dave Farley's 8 properties. Use when reviewing tests, assessing test suite quality, or analyzing test effectiveness against TDD best practices.
development
Refactoring assessment and patterns. Use after mutation testing validates test strength (MUTATE phase) to assess improvement opportunities.