npx claudepluginhub joshuaoliphant/claude-plugins --plugin autonomous-sdlcThis skill uses the workspace's default tool permissions.
Enforce the discipline of writing tests before implementation code. Every feature starts with a failing test (RED), passes with minimal code (GREEN), then improves through refactoring while green. Never skip the test-first step.
Guides Python TDD workflow: design typed interfaces, write failing pytest tests (AAA pattern), implement minimally to pass, refactor green, verify with coverage, ruff linting, and type checks.
Red-Green-Refactor cycle for test-first development. Write failing test, implement minimal code, refactor safely. Use when developing new features or fixing bugs in test-driven projects.
Share bugs, ideas, or general feedback.
Enforce the discipline of writing tests before implementation code. Every feature starts with a failing test (RED), passes with minimal code (GREEN), then improves through refactoring while green. Never skip the test-first step.
uv run pytest.tests/ directory with pytest configuration.RED: Write failing test
↓
GREEN: Write minimal code to pass
↓
REFACTOR: Improve code while keeping tests green
↓
(repeat)
tests/
├── unit/ # Fast, isolated tests
├── integration/ # Tests with real dependencies
└── e2e/ # Full system tests
Focus on meaningful coverage, not 100%:
Don't obsess over: simple getters/setters, framework boilerplate, generated code.
python ${CLAUDE_PLUGIN_ROOT}/scripts/feedback_manager.py autonomous-sdlc show-feedback
Apply relevant feedback: tdd_workflow, test_generation, general.
# tests/test_user_service.py
def test_create_user_returns_user_with_id():
"""Test that creating a user returns a user with an assigned ID."""
service = UserService()
user = service.create_user(name="Alice", email="alice@example.com")
assert user.id is not None
assert user.name == "Alice"
assert user.email == "alice@example.com"
Run to confirm failure:
uv run pytest tests/test_user_service.py::test_create_user_returns_user_with_id -x
# Expected: FAILED (UserService doesn't exist)
Write just enough code to make the test pass:
# src/user_service.py
from dataclasses import dataclass
import uuid
@dataclass
class User:
id: str
name: str
email: str
class UserService:
def create_user(self, name: str, email: str) -> User:
return User(id=str(uuid.uuid4()), name=name, email=email)
Run to confirm pass:
uv run pytest tests/test_user_service.py::test_create_user_returns_user_with_id -x
# Expected: PASSED
Refactoring means improving code structure without changing behavior. Do not add new features here.
# src/user_service.py — structural improvement only
from dataclasses import dataclass, field
import uuid
@dataclass
class User:
name: str
email: str
id: str = field(default_factory=lambda: str(uuid.uuid4()))
class UserService:
def create_user(self, name: str, email: str) -> User:
return User(name=name, email=email)
uv run pytest tests/test_user_service.py -x
# Should still pass — behavior unchanged, structure improved
New behavior requires a new failing test first:
# RED: Write failing test for validation
def test_create_user_validates_empty_name():
service = UserService()
with pytest.raises(ValueError, match="Name cannot be empty"):
service.create_user(name="", email="test@example.com")
uv run pytest tests/test_user_service.py -x
# Expected: FAILED (no validation exists yet)
# GREEN: Add just enough code to pass
class UserService:
def create_user(self, name: str, email: str) -> User:
if not name.strip():
raise ValueError("Name cannot be empty")
return User(name=name, email=email)
Then repeat for email validation, normalization, etc. — always RED first.
Before implementing any feature:
Working tests and implementation code produced through the red-green-refactor cycle. The test suite serves as living documentation of the system's behavior.