tdd
Comprehensive guide for Test-Driven Development (TDD) methodology. Use this skill when the user asks to implement features using TDD, write tests first, follow red-green-refactor cycle, or develop code with test-first approach. Also use when user mentions TDD, unit testing workflow, or wants to refactor code with test coverage.
What this skill does
# Test-Driven Development (TDD)
Test-Driven Development is a software development approach where tests are written before the actual code. This skill guides you through the TDD process, from writing your first failing test to refactoring production code.
## Core TDD Cycle: Red-Green-Refactor
The fundamental TDD cycle consists of three phases:
1. **Red**: Write a failing test
2. **Green**: Write minimal code to make the test pass
3. **Refactor**: Clean up code while keeping all tests passing
This cycle repeats for each new piece of functionality.
## The Six-Step TDD Process
Follow these steps for each feature or behavior you implement:
### 1. List Scenarios for the New Feature
Before writing any code, enumerate the expected behaviors and edge cases:
- Start with the basic case
- Add "what-if" scenarios: timeouts, missing data, invalid inputs, boundary conditions
- Consider use cases and user stories
- Document these as a checklist to work through
**Example scenarios for a calculator's add function:**
- Basic addition: 2 + 3 = 5
- Adding negative numbers: -5 + 3 = -2
- Adding zero: 5 + 0 = 5
- Large numbers: 1000000 + 2000000 = 3000000
### 2. Write a Test for One Item on the List
Select one scenario from your list and write an automated test that would pass if that behavior is correctly implemented.
**Key principles:**
- Test only one behavior per test
- Keep tests small and focused
- Use descriptive test names that explain the scenario
- Follow the test structure: Setup → Execution → Validation → Cleanup
**Example test structure:**
```python
def test_add_positive_numbers():
# Setup: Arrange the test state
calculator = Calculator()
# Execution: Act on the unit under test
result = calculator.add(2, 3)
# Validation: Assert the expected outcome
assert result == 5
# Cleanup: (if needed) restore state
```
### 3. Run All Tests - The New Test Should Fail
Execute your entire test suite. The new test must fail for the right reason (not due to syntax errors or missing imports).
**Why this matters:**
- Validates the test actually tests something and the harness works
- Confirms new code is genuinely needed
**What "fail for the right reason" means:**
- ✅ Good: Test fails with assertion error because expected behavior is missing
- ❌ Bad: Test fails due to NameError, ImportError, or other structural issues
### 4. Write the Simplest Code That Passes the New Test
Implement just enough code to make the failing test pass. Nothing more.
**Example:**
```python
# First test: add(2, 3) should return 5
def add(a, b):
return 5 # Hard-coded - perfectly acceptable at this stage!
# After more tests, evolve to:
def add(a, b):
return a + b
```
This "fake it till you make it" approach is intentional and valuable.
### 5. Run All Tests - Everything Should Pass
Execute the full test suite again. All tests, including the new one, must pass.
**If tests fail:**
- Make minimal changes to fix them
- Don't add new functionality while fixing
- If you can't fix quickly, consider reverting and starting over
- Keep commits small so reverting is easy
### 6. Refactor While Ensuring All Tests Continue to Pass
Now improve the code quality without changing behavior. Run tests after each refactoring step to ensure nothing breaks.
Remove duplication, extract methods, improve naming, eliminate hard-coded test data, and simplify logic.
### 7. Repeat
Return to step 1 or 2 with the next scenario on your list. Continue until all scenarios are implemented and tested.
## Test Structure Best Practices
Structure each test consistently for clarity and maintainability:
### Four-Phase Test Pattern
1. **Setup (Arrange)**: Prepare the system and test data
2. **Execution (Act)**: Invoke the behavior being tested
3. **Validation (Assert)**: Verify the results are correct
4. **Cleanup (Teardown)**: Restore pre-test state
### Test Organization Tips
- **Extract common setup/teardown**: Use test fixtures, setUp/tearDown methods, or before/after hooks
- **Keep tests independent**: Each test should work in isolation and in any order
- **Focus assertions**: Each test should verify one logical outcome
- **Name tests descriptively**: `test_add_returns_sum_of_two_positive_integers` is better than `test_add`
- **Treat test code with respect**: Test code deserves the same quality standards as production code
## Core TDD Principles
### KISS (Keep It Simple, Stupid)
Write the simplest code that makes tests pass. Complexity emerges from refactoring, not from initial implementation.
### YAGNI (You Aren't Gonna Need It)
Only implement features that are needed right now for passing tests. Don't add functionality for hypothetical future requirements.
### Test Units, Not Implementation Details
Test behavior through public interfaces, not internal implementation. This allows refactoring without breaking tests.
**Example:**
```python
# ❌ Bad: Testing implementation details
def test_internal_cache_structure():
obj = MyClass()
assert obj._cache == {} # Fragile - breaks if implementation changes
# ✅ Good: Testing behavior
def test_caching_improves_performance():
obj = MyClass()
first_call_time = time_function_call(obj.get_data)
second_call_time = time_function_call(obj.get_data)
assert second_call_time < first_call_time * 0.1
```
## Working with External Dependencies
### Use Test Doubles for Isolation
When code depends on external systems (databases, APIs, file systems), use test doubles to maintain fast, isolated unit tests:
- **Mock objects**: Verify interactions (was this method called?)
- **Stub objects**: Provide canned responses
- **Fake objects**: Working implementations with shortcuts (e.g., in-memory database)
- **Spy objects**: Record information about interactions
### Supplement with Integration Tests
Test doubles don't prove real connections work. Write integration tests separately to verify actual component interactions, but run them less frequently than unit tests.
### Testing Pyramid Strategy
- **Base (most tests)**: Fast unit tests with test doubles
- **Middle**: Moderate integration tests with real components
- **Top (fewest tests)**: Slow end-to-end tests of full system
## Anti-Patterns to Avoid
### Dependent Tests
❌ Tests that rely on execution order or state from other tests
**Why it's bad:** Creates fragile test suites where one failure cascades into many false negatives
**Solution:** Make each test independent with its own setup and teardown
### Testing Implementation Details
❌ Tests that verify internal structure rather than external behavior
**Why it's bad:** Tests break whenever you refactor, even if behavior is unchanged
**Solution:** Test only through public interfaces
### Slow-Running Tests
❌ Tests that take seconds or minutes to run
**Why it's bad:** Developers won't run them frequently, defeating TDD's rapid feedback loop
**Solution:** Use test doubles for external dependencies; move slow tests to separate integration suite
### All-Knowing Oracles
❌ Tests that verify every possible detail of output
**Why it's bad:** Expensive to maintain, brittle, and time-consuming
**Solution:** Verify only the aspects relevant to the behavior being tested
### Hard-Coded Test Data in Production Code
❌ Leaving test-specific values in production code after making tests pass
**Why it's bad:** Production code becomes polluted with test concerns
**Solution:** Refactor during the "Refactor" phase to remove test data
### Precise Timing Tests
❌ Tests that assert exact execution times or timestamps
**Why it's bad:** Flaky tests that fail randomly based on system load
**Solution:** Allow tolerance ranges (e.g., 5-10% margin) or test relative timing
## Commit Strategy
- Make small, frequent commits
- Commit after each green phase (tests passing)
- Write descriptive commit messages that reference the test
- If stuck, revert to last passing commit rather than debugging extensively
## TDD iRelated in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.