### New Content - Learning Paths section in README (Junior/Senior/Power User/PM tracks) - examples/ folder with 18 ready-to-use templates: - 4 agents (code-reviewer, test-writer, security-auditor, refactoring) - 2 skills (TDD workflow, security checklist) - 3 commands (commit, review-pr, generate-tests) - 4 hooks (bash + PowerShell for security, formatting) - 3 config templates (settings, MCP, gitignore) - 2 memory templates (project + personal CLAUDE.md) ### Governance - CHANGELOG.md: Version history (1.0.0 → 1.1.0 → Unreleased) - CONTRIBUTING.md: Contribution guidelines for community ### Documentation - llms.txt: Updated structure with new files/folders This update makes the guide more actionable with concrete templates and provides clear learning paths for different skill levels. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2.9 KiB
2.9 KiB
| name | description |
|---|---|
| tdd-workflow | Test-Driven Development workflow and best practices |
TDD Workflow Skill
The TDD Cycle
RED → GREEN → REFACTOR
↑__________________|
1. RED: Write a Failing Test
- Write the smallest test that fails
- Test should fail for the right reason
- Ensure the test actually runs
2. GREEN: Make it Pass
- Write minimal code to pass the test
- Don't optimize yet
- It's okay if the code is ugly
3. REFACTOR: Clean Up
- Improve code structure
- Remove duplication
- Keep tests passing
TDD Best Practices
Test Naming Convention
should_[expected behavior]_when_[condition]
Examples:
should_return_empty_array_when_no_itemsshould_throw_error_when_invalid_inputshould_calculate_total_when_items_present
Test Structure (AAA)
it('should calculate discount when coupon applied', () => {
// Arrange - Set up test data
const cart = new Cart();
cart.addItem({ price: 100 });
const coupon = new Coupon('10OFF', 10);
// Act - Execute the behavior
cart.applyCoupon(coupon);
// Assert - Verify the result
expect(cart.total).toBe(90);
});
Test Isolation
- Each test should be independent
- No shared state between tests
- Use
beforeEachfor common setup - Clean up in
afterEach
TDD Workflow Example
Feature: Add item to cart
Step 1: RED
describe('Cart', () => {
it('should add item to cart', () => {
const cart = new Cart();
cart.addItem({ id: 1, name: 'Book', price: 29.99 });
expect(cart.items).toHaveLength(1);
});
});
Run test → FAILS (Cart doesn't exist)
Step 2: GREEN
class Cart {
items = [];
addItem(item) {
this.items.push(item);
}
}
Run test → PASSES
Step 3: REFACTOR
class Cart {
private _items: CartItem[] = [];
get items(): ReadonlyArray<CartItem> {
return this._items;
}
addItem(item: CartItem): void {
this._items.push(item);
}
}
Run test → Still PASSES
Next iteration: Calculate total
Repeat the cycle for each new behavior.
When to Use TDD
Good for TDD
- Business logic
- Complex algorithms
- API endpoints
- State management
- Utility functions
Less Suitable
- UI layout (visual testing better)
- Database migrations
- External integrations (use integration tests)
- Exploratory/prototype code
Common TDD Mistakes
- Writing too much test - Start with smallest failing test
- Writing too much code - Only enough to pass
- Skipping refactor - Technical debt accumulates
- Testing implementation - Test behavior, not internals
- Ignoring failing tests - Fix or delete, never skip
Test Doubles
| Type | Purpose | Example |
|---|---|---|
| Stub | Return fixed data | jest.fn().mockReturnValue(42) |
| Mock | Verify interactions | expect(mock).toHaveBeenCalled() |
| Spy | Track calls | jest.spyOn(obj, 'method') |
| Fake | Simplified implementation | In-memory database |