From autonomous-sdlc
Enforces TDD red-green-refactor cycle in Python projects using uv + pytest: organizes tests into unit/integration/e2e, runs uv pytest commands, loads autonomous-sdlc feedback.
How this skill is triggered — by the user, by Claude, or both
Slash command
/autonomous-sdlc:tdd-workflowThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
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.
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="[email protected]")
assert user.id is not None
assert user.name == "Alice"
assert user.email == "[email protected]"
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="[email protected]")
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.
npx claudepluginhub joshuaoliphant/claude-plugins --plugin autonomous-sdlcGuides 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.