.opencode/skill/tdd/SKILL.md
Test-Driven Development workflow with RED-GREEN-REFACTOR, lore from Kent Beck, Michael Feathers, and Ousterhout's counterpoint
npx skillsauth add joelhooks/swarm-tools 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.
1. RED - Write failing test first (define expected behavior)
2. GREEN - Minimal implementation to pass (don't over-engineer)
3. REFACTOR - Clean up, remove duplication, run tests again
"The act of writing a unit test is more an act of design than verification."
"The most powerful feature-addition technique I know of is test-driven development."
"Kent Beck baked this habit of writing the test first into a technique called Test-Driven Development."
"The problem with test-driven development is that it focuses attention on getting specific features working, rather than finding the best design."
When TDD can hurt:
The balance:
✅ Use TDD for:
❌ Skip TDD for:
# 1. Write test, watch it fail
bun test src/thing.test.ts # RED - test fails
# 2. Implement minimal code to pass
bun test src/thing.test.ts # GREEN - test passes
# 3. Refactor, tests still pass
bun test src/thing.test.ts # GREEN - still passing
# 4. Repeat for next behavior
Write the assertion first, then work backwards:
// Start here
expect(result).toBe(42);
// Then figure out what 'result' is
const result = calculate(input);
// Then figure out what 'input' is
const input = { value: 21 };
Use multiple examples to drive generalization:
it("doubles 2", () => expect(double(2)).toBe(4));
it("doubles 3", () => expect(double(3)).toBe(6));
// Now you MUST implement the general solution
When the solution is obvious, just write it:
function add(a: number, b: number): number {
return a + b; // Don't fake this
}
When unsure, start with hardcoded values:
// First pass
function fibonacci(n: number): number {
return 1; // Passes for n=1
}
// Add test for n=2, then generalize
/\
/ \ E2E (few)
/----\
/ \ Integration (some)
/--------\
/ \ Unit (many)
--------------
When working on a bead:
beads_start(id="bd-123")beads_close(id="bd-123", reason="Done: tests passing")development
Patterns for testing code effectively. Use when breaking dependencies for testability, adding tests to existing code, understanding unfamiliar code through characterization tests, or deciding how to structure tests. Covers seams, dependency injection, test doubles, and safe refactoring techniques from Michael Feathers.
tools
Principles for building reusable coding systems. Use when designing modules, APIs, CLIs, or any code meant to be used by others. Based on "A Philosophy of Software Design" by John Ousterhout. Covers deep modules, complexity management, and design red flags.
development
Multi-agent coordination patterns for OpenCode swarm workflows. Use when working on complex tasks that benefit from parallelization, when coordinating multiple agents, or when managing task decomposition. Do NOT use for simple single-agent tasks.
development
Meta-skill for generating new skills with proper format and structure. Use when creating new skills for the swarm system or when agents need to generate skill scaffolds. Ensures skills follow conventions (frontmatter format, directory structure, bundled resources).