assets/skills/review/tdd/SKILL.md
Test-Driven Development workflow. Use when doing TDD, writing tests first, or when user says "tdd", "test first", "test driven", "red green refactor".
npx skillsauth add phuthuycoding/moicle review-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.
Red-Green-Refactor cycle: write failing test → write minimal code to pass → refactor while green.
/research-spike (throwaway, no tests)Detect stack via ~/.claude/architecture/_shared/stack-detection.md. Architecture doc tells you:
_test.go next to source, __tests__/, tests/Feature/, etc.)testing, Jest, Pest, flutter_test) ┌──────┐ ┌───────┐ ┌──────────┐
┌──▶│ RED │───▶│ GREEN │───▶│ REFACTOR │──┐
│ └──────┘ └───────┘ └──────────┘ │
│ (fail) (minimal) (cleanup) │
└──────────────────────────────────────────┘
next requirement
Goal: describe wanted behavior with a test that fails because the code doesn't exist yet.
should_<behavior>_when_<condition> (snake_case for Go / Python)it("returns X when Y", ...) (Jest / Mocha)test_<behavior>_<condition> (PHPUnit / Pest)// Arrange — set up inputs and mocks
// Act — call function under test
// Assert — verify result / state / interactions
Goal: smallest amount of code to pass. Resist "doing it properly" — refactor is next.
Goal: improve structure without changing behavior. Tests stay green throughout.
// TODO: refactor linked to a follow-up| Layer | Test type | Dependencies | Example |
|-------|-----------|--------------|---------|
| Value Object | Unit (pure) | None | Money.add() |
| Entity | Unit (pure) | None | Order.cancel() raises event |
| UseCase | Unit | Mock ports | CreateOrder calls OrderStore.save() |
| Service | Unit | Mock usecase | Delegates correctly |
| Handler / Controller | Integration | Real router, mock service | POST /orders returns 201 |
| Infrastructure | Integration | Real DB / testcontainers | OrderRepository.save() persists |
| Listener | Unit | Mock infra | on_order_created sends email |
| API contract (cross-service) | Contract test | Real / sandboxed external | OpenAPI / Pact / Wiremock |
| Dependency type | Use real | Use stub / fake | Use mock | |-----------------|----------|-----------------|----------| | Value objects, entities (pure) | ✅ always | — | never (brittle) | | Stdlib (time, fs, env) | mostly — use clock / fs abstraction in domain | for determinism | rarely | | Repository / port | testcontainers in infra tests | in-memory fake for usecase tests | only when verifying call args | | External HTTP API | sandbox URL in integration | wiremock / msw for predictable cases | for failure-mode tests | | Auth / session | real in integration | fake user in unit | rarely | | Time | clock abstraction | fixed clock in tests | rarely |
Stub vs fake vs mock:
returnsBalance(100))InMemoryOrderStore)expect(store.save).toHaveBeenCalledWith(...))Prefer fake for repository tests (closest to real behavior). Use mock only when call args are the assertion.
For pure logic with many edge cases (parsers, math, encoders), use property-based tests:
testing/quick, gopterfast-checkhypothesisgladosPattern: "for all valid input X, property P holds." Generates 100s of cases including edge cases you wouldn't think of.
Example (TS, fast-check):
test("reverse twice = identity", () => {
fc.assert(fc.property(fc.array(fc.string()), (arr) => {
expect(reverse(reverse(arr))).toEqual(arr);
}));
});
Use it for: serializers, parsers, math, sorting, encoding/decoding. Not for: business workflows.
| Mistake | Why it's bad | Fix | |---------|--------------|-----| | Writing tests AFTER the code | Tests what's written, not what's needed | Always RED first | | Testing implementation, not behavior | Refactor breaks tests | Assert outputs / observable state | | One test, many behaviors | Failure message unclear | One behavior per test | | Mocking value objects | Brittle, no benefit | Use real — they're pure | | Skipping REFACTOR | Tech debt accumulates | It's a phase, not optional | | Test depends on order | Flaky | Each test sets up its own state | | Slow tests (>1s each) | People stop running them | Move to integration tier; keep unit <100ms | | 100% coverage chase | Forces tests for trivial code | Aim for high-value coverage on domain |
## TDD Cycle Complete: {feature}
### Cycles
| # | RED (behavior) | GREEN (code added) | REFACTOR |
|---|----------------|--------------------|----------|
| 1 | rejects negative amount | guard in constructor | extracted validator |
| 2 | transitions PENDING → ACTIVE | added transition method | — |
### Test Coverage
- {N} tests, all passing
- Domain coverage: {%} (target ≥80%)
### Files
- Tests: {paths}
- Code: {paths}
| When | Use |
|------|-----|
| Building feature from scratch (with TDD inside) | /feature-new + this skill |
| Adding regression test for a bug | /fix-hotfix or /fix-root-cause → then this skill |
| Refactoring untested legacy code | /feature-refactor (add tests first) |
| Reviewing test quality on a PR | /review-pr |
| Phase | Agent | Purpose |
|-------|-------|---------|
| RED | @test-writer | Failing tests first |
| GREEN | Stack-specific dev agent | Minimal implementation |
| REFACTOR | @refactor | Patterns + cleanup |
| REFACTOR | @code-reviewer | Review refactored code |
| REFACTOR | @perf-optimizer | Perf tweaks (only with benchmarks) |
development
Thorough pull request review workflow with architecture compliance checks. Use when reviewing pull requests, checking code changes, or when user says "review pr", "check pr", "review code", "pr review", "review pull request".
development
Review local branch changes for architecture compliance, conventions, and code quality before pushing/PR. Stack-aware — detects the project stack and applies the matching rules. Use when user says "review changes", "review branch", "check branch", "check changes", "review my code", "review before pr".
testing
DDD architecture compliance review with automated checks and review loop. Use when user says "architect-review", "architecture review", "review architecture", "check architecture", "review ddd", "ddd review".
development
Research solutions on the internet for a given topic or the current conversation context. Use when user says "research", "tìm giải pháp", "search solution", "investigate", "find best practice", "so sánh giải pháp".