Test
Purpose
TDD enforcement and testing skill. Tests are executable specifications -- they define what the system does before the system does it. Maximum confidence per minute of developer time.
When to Use
tdd: driving new features test-first (RED-GREEN-REFACTOR)
run: writing and executing tests for existing code
gap: analyzing coverage gaps and missing edge cases
plan: designing test strategy before writing tests
Process
Mode: tdd (RED-GREEN-REFACTOR)
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
Phase RED -- Write Failing Test
- Write ONE test showing what SHOULD happen
- Name:
test_<unit>_<scenario>_<expected_outcome>
- AAA pattern: Arrange, Act, Assert (visually separated)
- Run test -- confirm FAIL for the expected reason (missing feature, not syntax error)
- Produce Implementation Contract:
## Implementation Contract
- Test files: [exact paths]
- Verification: [exact command]
- Failure reason: [why it fails -- tied to missing behavior]
- Constraint: DO NOT modify these test files during GREEN
- STOP. Do not implement.
Phase GREEN -- Minimal Code
- Read the Implementation Contract
- DO NOT modify test files (they are immutable)
- Write the simplest code to make the test pass (YAGNI)
- Run test -- confirm PASS
- Run ALL tests -- confirm no regressions
If the test still fails: fix your code, not the test.
Phase REFACTOR -- Clean Up (after GREEN only)
- Remove duplication, improve names, extract helpers
- Tests MUST stay green throughout
- Do NOT add behavior during refactor
Mode: run
- Detect test framework from project files
- Follow existing conventions (directory structure, naming, fixtures)
- Write tests using AAA pattern with descriptive names
- Run with stack-appropriate command
- Report results: pass/fail count, coverage delta
Mode: gap
- Run coverage tool with branch coverage enabled
- Identify untested critical paths (business logic > glue code)
- Check for missing edge cases: null, empty, boundary, error paths
- Produce gap report with prioritized recommendations
Mode: plan
- Map the testing surface (modules, public APIs, critical paths)
- Assign test categories: unit, integration, e2e
- Define coverage targets per module
- Identify infrastructure needs (test containers, fixtures, fakes)
Stack Commands
| Stack |
Runner |
Coverage |
Async |
| Python |
uv run pytest |
pytest-cov (branch=true) |
asyncio_mode = "auto" |
| TypeScript |
vitest or jest |
c8 / istanbul |
async/await |
| .NET |
dotnet test + xUnit |
coverlet |
async Task |
| Rust |
cargo test |
cargo tarpaulin |
#[tokio::test] |
| Go |
go test ./... |
go test -cover |
goroutine tests |
Testing Rules
Fakes over mocks. Mocks test implementation details. Fakes implement the same interface.
Mocks are acceptable ONLY for:
- Verifying something was NOT called
- Simulating transient errors for retry logic
- Third-party libraries (but wrap in your own adapter first)
AAA pattern (non-negotiable):
# Arrange -- set up inputs and dependencies
# Act -- call the function under test
# Assert -- verify the outcome
Name pattern: test_<unit>_<scenario>_<expected_outcome>
- Good:
test_parse_email_rejects_missing_at_symbol
- Bad:
test_parse_email, test_1, test_it_works
Anti-Patterns (Reject These)
| Anti-Pattern |
Why It Fails |
| Testing the mock |
Proves the mock works, not the code |
| No-op test (assert True) |
Tests nothing, inflates coverage |
| Testing implementation |
Breaks on refactor, proves nothing about behavior |
| Huge test setup |
Design is too coupled -- simplify the interface |
| sleep() for sync |
Flaky -- use events, barriers, wait_for |
| Exact float comparison |
Flaky -- use approx/closeTo |
Iron Law
If tests are wrong, escalate to the user. NEVER weaken, skip, or modify tests to make implementation easier. "Tests are wrong" means the requirement changed -- not that passing them is hard.
Common Mistakes
- Writing tests after implementation (tests-after prove what IS, not what SHOULD be)
- Testing private methods (test the public API)
- 100% coverage with meaningless assertions
- Skipping edge cases (null, empty, boundary, concurrent access)
- Not running ALL tests after changes
Integration
- Called by:
/ai-dispatch (build tasks), ai-build agent (TDD mode), user directly
- Calls: stack-specific test runners
- Transitions to:
ai-build (GREEN phase), /ai-verify (coverage validation)
$ARGUMENTS
1---2name: ai-test3description: Use when writing tests, enforcing TDD (RED-GREEN-REFACTOR), analyzing coverage gaps, or planning test strategy. Supports Python, TypeScript, .NET, Rust, Go.4---5
6
7# Test
8
9## Purpose
10
11TDD enforcement and testing skill. Tests are executable specifications -- they define what the system does before the system does it. Maximum confidence per minute of developer time.
12
13## When to Use
14
15- `tdd`: driving new features test-first (RED-GREEN-REFACTOR)
16- `run`: writing and executing tests for existing code
17- `gap`: analyzing coverage gaps and missing edge cases
18- `plan`: designing test strategy before writing tests
19
20## Process
21
22### Mode: tdd (RED-GREEN-REFACTOR)
23
24```
25NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
26```
27
28**Phase RED -- Write Failing Test**
29
301. Write ONE test showing what SHOULD happen
312. Name: `test_<unit>_<scenario>_<expected_outcome>`
323. AAA pattern: Arrange, Act, Assert (visually separated)
334. Run test -- confirm FAIL for the expected reason (missing feature, not syntax error)
345. Produce Implementation Contract:
35
36```markdown
37## Implementation Contract
38- Test files: [exact paths]
39- Verification: [exact command]
40- Failure reason: [why it fails -- tied to missing behavior]
41- Constraint: DO NOT modify these test files during GREEN
42```
43
446. STOP. Do not implement.
45
46**Phase GREEN -- Minimal Code**
47
481. Read the Implementation Contract
492. DO NOT modify test files (they are immutable)
503. Write the simplest code to make the test pass (YAGNI)
514. Run test -- confirm PASS
525. Run ALL tests -- confirm no regressions
53
54If the test still fails: fix your code, not the test.
55
56**Phase REFACTOR -- Clean Up (after GREEN only)**
57
58- Remove duplication, improve names, extract helpers
59- Tests MUST stay green throughout
60- Do NOT add behavior during refactor
61
62### Mode: run
63
641. Detect test framework from project files
652. Follow existing conventions (directory structure, naming, fixtures)
663. Write tests using AAA pattern with descriptive names
674. Run with stack-appropriate command
685. Report results: pass/fail count, coverage delta
69
70### Mode: gap
71
721. Run coverage tool with branch coverage enabled
732. Identify untested critical paths (business logic > glue code)
743. Check for missing edge cases: null, empty, boundary, error paths
754. Produce gap report with prioritized recommendations
76
77### Mode: plan
78
791. Map the testing surface (modules, public APIs, critical paths)
802. Assign test categories: unit, integration, e2e
813. Define coverage targets per module
824. Identify infrastructure needs (test containers, fixtures, fakes)
83
84## Stack Commands
85
86| Stack | Runner | Coverage | Async |
87|-------|--------|----------|-------|
88| Python | `uv run pytest` | `pytest-cov` (branch=true) | `asyncio_mode = "auto"` |
89| TypeScript | `vitest` or `jest` | `c8` / `istanbul` | `async/await` |
90| .NET | `dotnet test` + xUnit | `coverlet` | `async Task` |
91| Rust | `cargo test` | `cargo tarpaulin` | `#[tokio::test]` |
92| Go | `go test ./...` | `go test -cover` | goroutine tests |
93
94## Testing Rules
95
96**Fakes over mocks**. Mocks test implementation details. Fakes implement the same interface.
97
98Mocks are acceptable ONLY for:
991. Verifying something was NOT called
1002. Simulating transient errors for retry logic
1013. Third-party libraries (but wrap in your own adapter first)
102
103**AAA pattern** (non-negotiable):
104
105```python
106# Arrange -- set up inputs and dependencies
107# Act -- call the function under test
108# Assert -- verify the outcome
109```
110
111**Name pattern**: `test_<unit>_<scenario>_<expected_outcome>`
112- Good: `test_parse_email_rejects_missing_at_symbol`
113- Bad: `test_parse_email`, `test_1`, `test_it_works`
114
115## Anti-Patterns (Reject These)
116
117| Anti-Pattern | Why It Fails |
118|-------------|-------------|
119| Testing the mock | Proves the mock works, not the code |
120| No-op test (assert True) | Tests nothing, inflates coverage |
121| Testing implementation | Breaks on refactor, proves nothing about behavior |
122| Huge test setup | Design is too coupled -- simplify the interface |
123| sleep() for sync | Flaky -- use events, barriers, wait_for |
124| Exact float comparison | Flaky -- use approx/closeTo |
125
126## Iron Law
127
128If tests are wrong, escalate to the user. NEVER weaken, skip, or modify tests to make implementation easier. "Tests are wrong" means the requirement changed -- not that passing them is hard.
129
130## Common Mistakes
131
132- Writing tests after implementation (tests-after prove what IS, not what SHOULD be)
133- Testing private methods (test the public API)
134- 100% coverage with meaningless assertions
135- Skipping edge cases (null, empty, boundary, concurrent access)
136- Not running ALL tests after changes
137
138## Integration
139
140- **Called by**: `/ai-dispatch` (build tasks), `ai-build agent` (TDD mode), user directly
141- **Calls**: stack-specific test runners
142- **Transitions to**: `ai-build` (GREEN phase), `/ai-verify` (coverage validation)
143
144$ARGUMENTS