feat: add verification and debugging workflow skills
This commit is contained in:
77
.config/opencode/skills/test-driven-development/SKILL.md
Normal file
77
.config/opencode/skills/test-driven-development/SKILL.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
name: test-driven-development
|
||||
description: Enforce test-first development for features and bug fixes — no production
|
||||
code before a failing test
|
||||
permalink: opencode-config/skills/test-driven-development/skill
|
||||
---
|
||||
|
||||
# Test-Driven Development (TDD)
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this skill when implementing behavior changes:
|
||||
- New features
|
||||
- Bug fixes
|
||||
- Refactors that alter behavior
|
||||
|
||||
If the work introduces or changes production behavior, TDD applies.
|
||||
|
||||
## Core Rule
|
||||
|
||||
```
|
||||
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
|
||||
```
|
||||
|
||||
If production code was written first, delete or revert it and restart from a failing test.
|
||||
|
||||
## Red → Green → Refactor Loop
|
||||
|
||||
### 1) RED: Write one failing test
|
||||
- Write one small test that expresses the next expected behavior.
|
||||
- Prefer clear test names describing observable behavior.
|
||||
- Use real behavior paths where practical; mock only when isolation is required.
|
||||
|
||||
### 2) Verify RED (mandatory)
|
||||
Run the new test and confirm:
|
||||
- It fails (not just errors)
|
||||
- It fails for the expected reason
|
||||
- It fails because behavior is missing, not because the test is broken
|
||||
|
||||
If it passes immediately, the test is not proving the new behavior. Fix the test first.
|
||||
|
||||
### 3) GREEN: Add minimal production code
|
||||
- Implement only enough code to make the failing test pass.
|
||||
- Do not add extra features, abstractions, or speculative options.
|
||||
|
||||
### 4) Verify GREEN (mandatory)
|
||||
Run the test suite scope needed for confidence:
|
||||
- New test passes
|
||||
- Related tests still pass
|
||||
|
||||
If failures appear, fix production code first unless requirements changed.
|
||||
|
||||
### 5) REFACTOR
|
||||
- Improve names, remove duplication, and simplify structure.
|
||||
- Keep behavior unchanged.
|
||||
- Keep tests green throughout.
|
||||
|
||||
Repeat for the next behavior.
|
||||
|
||||
## Quality Checks Before Completion
|
||||
|
||||
- [ ] Each behavior change has a test that failed before implementation
|
||||
- [ ] New tests failed for the expected reason first
|
||||
- [ ] Production code was added only after RED was observed
|
||||
- [ ] Tests now pass cleanly
|
||||
- [ ] Edge cases for changed behavior are covered
|
||||
|
||||
## Practical Guardrails
|
||||
|
||||
- "I'll write tests after" is not TDD.
|
||||
- Manual verification does not replace automated failing-then-passing tests.
|
||||
- If a test is hard to write, treat it as design feedback and simplify interfaces.
|
||||
- Keep test intent focused on behavior, not internals.
|
||||
|
||||
## Related Reference
|
||||
|
||||
For common mistakes around mocks and test design, see [testing-anti-patterns](./testing-anti-patterns.md).
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
title: testing-anti-patterns
|
||||
type: note
|
||||
permalink: opencode-config/skills/test-driven-development/testing-anti-patterns
|
||||
---
|
||||
|
||||
# Testing Anti-Patterns
|
||||
|
||||
Use this reference when writing/changing tests, introducing mocks, or considering test-only production APIs.
|
||||
|
||||
## Core Principle
|
||||
|
||||
Test real behavior, not mock behavior.
|
||||
|
||||
Mocks are isolation tools, not the subject under test.
|
||||
|
||||
## Anti-Pattern 1: Testing mock existence instead of behavior
|
||||
|
||||
**Problem:** Assertions only prove a mock rendered or was called, not that business behavior is correct.
|
||||
|
||||
**Fix:** Assert observable behavior of the unit/system under test. If possible, avoid mocking the component being validated.
|
||||
|
||||
Gate check before assertions on mocked elements:
|
||||
- Am I validating system behavior or only that a mock exists?
|
||||
- If only mock existence, rewrite the test.
|
||||
|
||||
## Anti-Pattern 2: Adding test-only methods to production code
|
||||
|
||||
**Problem:** Production classes gain methods used only by tests (cleanup hooks, debug helpers), polluting real APIs.
|
||||
|
||||
**Fix:** Move test-only setup/cleanup into test utilities or fixtures.
|
||||
|
||||
Gate check before adding a production method:
|
||||
- Is this method needed in production behavior?
|
||||
- Is this resource lifecycle actually owned by this class?
|
||||
- If not, keep it out of production code.
|
||||
|
||||
## Anti-Pattern 3: Mocking without understanding dependencies
|
||||
|
||||
**Problem:** High-level mocks remove side effects the test depends on, causing false positives/negatives.
|
||||
|
||||
**Fix:** Understand dependency flow first, then mock the lowest-cost external boundary while preserving needed behavior.
|
||||
|
||||
Gate check before adding a mock:
|
||||
1. What side effects does the real method perform?
|
||||
2. Which side effects does this test rely on?
|
||||
3. Can I mock a lower-level boundary instead?
|
||||
|
||||
If unsure, run against real implementation first, then add minimal mocking.
|
||||
|
||||
## Anti-Pattern 4: Incomplete mock structures
|
||||
|
||||
**Problem:** Mocks include only fields used immediately, omitting fields consumed downstream.
|
||||
|
||||
**Fix:** Mirror complete response/object shapes used in real flows.
|
||||
|
||||
Gate check for mocked data:
|
||||
- Does this mock match the real schema/shape fully enough for downstream consumers?
|
||||
- If uncertain, include the full documented structure.
|
||||
|
||||
## Anti-Pattern 5: Treating tests as a follow-up phase
|
||||
|
||||
**Problem:** "Implementation complete, tests later" breaks TDD and reduces confidence.
|
||||
|
||||
**Fix:** Keep tests inside the implementation loop:
|
||||
1. Write failing test
|
||||
2. Implement minimum code
|
||||
3. Re-run tests
|
||||
4. Refactor safely
|
||||
|
||||
## Quick Red Flags
|
||||
|
||||
- Assertions target `*-mock` markers rather than behavior outcomes
|
||||
- Methods exist only for tests in production classes
|
||||
- Mock setup dominates test logic
|
||||
- You cannot explain why each mock is necessary
|
||||
- Tests are written only after code "already works"
|
||||
|
||||
## Bottom Line
|
||||
|
||||
If a test does not fail first for the intended reason, it is not validating the behavior change reliably.
|
||||
|
||||
Keep TDD strict: failing test first, then minimal code.
|
||||
Reference in New Issue
Block a user