From programmer
Apply test architecture patterns including DSL design, test adapters, and fixture organization. Use when writing tests, designing test structure, or when user asks about testing approach. Activates for phrases like "how should I test", "test structure", "test adapter", "test DSL", or when creating new test files.
npx claudepluginhub nicolaei/claude-plugins --plugin programmerThis skill uses the workspace's default tool permissions.
- **Natural isolation** - No mocks in functional core tests
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
If you need to mock something, it's a sign of wrong boundaries:
The need to mock indicates the code under test has too many dependencies or side effects.
Create DSL methods for domain operations that model business behavior:
# GOOD: Domain operations as DSL
event = organizer.create_event("Team Meeting")
attendee.rsvp_to_event(event, "yes")
result = cli.run("migrate")
Use Python's standard APIs for infrastructure and state setup:
# GOOD: Direct Python APIs for setup
main_file = scenario.file_system / "terraform" / "main.tf"
main_file.write_text("terraform content")
scenario.git_state.is_clean = True
cli.inputs["folder"] = "terraform"
# BAD: Fluent/builder patterns for setup
repo.add_file("main.tf").with_content("...").in_folder("terraform")
scenario.with_clean_git_state().and_terraform_files()
Implement application ports with in-memory versions for testing:
from collections.abc import MutableMapping
class InMemoryEventStorage(MutableMapping[str, Event]):
"""Test adapter implementing storage port."""
def __init__(self) -> None:
self._events: dict[str, Event] = {}
def __getitem__(self, key: str) -> Event:
return self._events[key]
def __setitem__(self, key: str, value: Event) -> None:
self._events[key] = value
def __delitem__(self, key: str) -> None:
del self._events[key]
def __iter__(self):
return iter(self._events)
def __len__(self) -> int:
return len(self._events)
class FakeEmailService:
"""Test adapter for email service."""
def __init__(self) -> None:
self.sent_emails: list[tuple[str, str, str]] = []
def send(self, to: str, subject: str, body: str) -> None:
self.sent_emails.append((to, subject, body))
@pytest.fixture
def scenario():
"""Create directory structure only, not content."""
s = MigrationScenario("my-repo")
template_dir = s.file_system / "terraform" / "template"
template_dir.mkdir(parents=True)
s.set_clean_git_state()
return s
def test_migration_upgrades_modules(scenario):
"""Test writes actual content."""
# Write specific content for this test
template_main = scenario.file_system / "terraform" / "template" / "main.tf"
template_main.write_text("""
module "loadbalancer" {
source = "github.com/example/module"
}
""")
result = scenario.run_migration()
assert result.success
def test_user_can_create_and_rsvp_to_event():
"""High-level scenario testing complete flow."""
# Arrange
app = create_test_app()
organizer = TestOrganizer(app)
attendee = TestAttendee(app)
# Act
event = organizer.create_event("Team Meeting")
attendee.rsvp_to_event(event, response="yes")
# Assert
assert event.attendee_count == 1
def test_event_capacity_calculation():
"""Test pure business logic - no mocks needed."""
event = Event(name="Meeting", max_attendees=5)
rsvps = [RSVP("alice", "yes"), RSVP("bob", "no")]
remaining = calculate_remaining_capacity(event, rsvps)
assert remaining == 4
from hypothesis import given, strategies as st
@given(st.integers(min_value=0), st.integers(min_value=0))
def test_capacity_never_negative(max_attendees, yes_count):
event = Event(max_attendees=max_attendees)
remaining = calculate_remaining(event, yes_count)
assert remaining >= 0 or remaining is None