tdd-workflow
Use TDD workflow (Red-Green-Refactor-Validate) when creating or modifying any business logic, use cases, or domain code. MANDATORY for all implementations. Apply when user requests new features, bug fixes, or refactoring that involves testable code.
When & Why to Use This Skill
This Claude skill enforces a rigorous Test-Driven Development (TDD) workflow—Red, Green, Refactor, and Validate—designed to ensure high-quality, maintainable code. It guides the development process from initial failing tests through minimal implementation to final quality assurance, making it mandatory for robust business logic and domain-driven design.
Use Cases
- Developing new business features by defining expected behavior through unit tests before any implementation code is written.
- Refactoring legacy domain code or complex use cases with the safety of a comprehensive test suite to prevent regressions.
- Debugging and fixing software defects by first creating a failing test case that reproduces the issue to validate the eventual fix.
- Enforcing strict quality gates and static analysis standards (like PHPStan and CS-Fixer) to ensure code remains clean and compliant before every commit.
| name | tdd-workflow |
|---|---|
| description | Use TDD workflow (Red-Green-Refactor-Validate) when creating or modifying any business logic, use cases, or domain code. MANDATORY for all implementations. Apply when user requests new features, bug fixes, or refactoring that involves testable code. |
TDD Workflow
Test-Driven Development cycle: Red → Green → Refactor → Validate
MANDATORY for all business logic, use cases, and domain code implementations.
Process
| Phase | Goal | Action | Expected | Template |
|---|---|---|---|---|
| RED | Define behavior | Write failing test | Test FAILS | .claude/templates/test-unit.php.tpl |
| GREEN | Pass test | Minimal implementation | Test PASSES | .claude/templates/use-case.php.tpl, request.php.tpl |
| REFACTOR | Clean code | Improve without breaking tests | Tests still pass | - |
| VALIDATE | Quality gates | make qa |
All gates pass | - |
1. RED: Write Failing Test
File: BC/Tests/UseCases/Entity/ActionEntity/ActionEntityTest.php
Steps:
- Use template:
.claude/templates/test-unit.php.tpl - Write assertions (explicit expectations)
- Use DataBuilder for test data (NOT Foundry)
- Mock dependencies:
expects()->once() - Run:
php bin/phpunit path/to/Test.php
Expected: FAILURE (class not found or assertion fails)
Critical: Test MUST fail for the right reason
2. GREEN: Minimal Implementation
Create Request (BC/UseCases/Entity/ActionEntity/ActionEntityRequest.php):
- Template:
.claude/templates/request.php.tpl readonlyclass, public fields only
Create UseCase (BC/UseCases/Entity/ActionEntity/ActionEntity.php):
- Template:
.claude/templates/use-case.php.tpl readonlyclass, singleexecute()method- Inject Repository (commands) OR Finder (queries)
Run: php bin/phpunit path/to/Test.php
Expected: OK (test passes)
Critical: Minimal code only, no premature optimization
3. REFACTOR: Clean Code
Commands:
make cs-fixer # Auto-fix code style
make stan # Static analysis (level 9)
make ta # Verify tests still pass
Improvements:
- Better naming (domain language)
- Extract private methods if needed
- Add PHPDoc (
@param,@return,@throws) - Simplify logic
Critical: Tests MUST still pass after refactoring
4. VALIDATE: Full QA
Command:
make qa
Gates (all must pass):
- PHPStan level 9: 0 errors
- CS-Fixer: formatted
- PHPCS: compliant
- Rector: no suggestions
- Deptrac: architecture valid
- All tests: passing
Critical: NEVER commit without make qa passing
Rules
ALWAYS:
- Start with test (Red phase)
- Test MUST fail before implementation
- Minimal implementation first (Green)
- Refactor only when tests pass
make qabefore commit
NEVER:
- Code before test
- Premature optimization (in Green)
- Refactor without passing tests
- Commit without
make qa
Repository vs Finder
| Aspect | Repository | Finder |
|---|---|---|
| Use | Commands (CUD) | Queries (R) |
| Methods | get*(), save(), delete() |
find*(), findAll() |
| Not found | Throws exception | Returns null/[] |
| Location | BC/Entities/Repository/ |
BC/UseCases/Gateway/Finder/ |
See: docs/GLOSSARY.md#repository-vs-finder for detailed comparison
Templates
test-unit.php.tpl- Unit testrequest.php.tpl- Request DTOuse-case.php.tpl- UseCase
Location: .claude/templates/
References
- Quick patterns:
docs/QUICK_REF.md#usecase-pattern - Testing strategy:
docs/testing.md - Commands:
docs/reference.md - Architecture:
docs/architecture.md