← Back to list

tdd-workflow
by lackeyjb
Context-Driven Development framework for Claude Code. Inspired by https://github.com/gemini-cli-extensions/conductor
⭐ 9🍴 0📅 Jan 23, 2026
SKILL.md
name: tdd-workflow description: Test-Driven Development guidance. Use when writing code, implementing features, or fixing bugs in projects that follow TDD methodology. Provides the Red-Green-Refactor cycle structure.
TDD Workflow Skill
This skill provides guidance for Test-Driven Development methodology.
The Core Cycle
┌─────────────────────────────────────────────────┐
│ │
│ ┌───────┐ ┌───────┐ ┌──────────┐ │
│ │ RED │ ──▶ │ GREEN │ ──▶ │ REFACTOR │ │
│ └───────┘ └───────┘ └──────────┘ │
│ │ │ │
│ └─────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────┘
Phase 1: RED - Write a Failing Test
Purpose
Define the expected behavior BEFORE writing implementation.
Actions
- Create or open test file
- Write a test that describes ONE behavior
- Run the test
- Verify it FAILS (important!)
Example (TypeScript/Jest)
describe('UserService', () => {
describe('createUser', () => {
it('should create a user with valid email', async () => {
const user = await userService.createUser({
email: 'test@example.com',
name: 'Test User'
});
expect(user.id).toBeDefined();
expect(user.email).toBe('test@example.com');
});
it('should throw error for invalid email', async () => {
await expect(
userService.createUser({ email: 'invalid', name: 'Test' })
).rejects.toThrow('Invalid email format');
});
});
});
Common Mistakes
- Writing tests that pass immediately (means the test is wrong)
- Testing implementation details instead of behavior
- Writing too many tests before any implementation
Phase 2: GREEN - Make It Pass
Purpose
Write the MINIMUM code to make the test pass.
Actions
- Implement just enough to pass the failing test
- No extra features
- No optimization
- Run tests to verify PASS
Example
// MINIMUM implementation to pass the tests above
class UserService {
async createUser(data: { email: string; name: string }) {
if (!data.email.includes('@')) {
throw new Error('Invalid email format');
}
return {
id: crypto.randomUUID(),
email: data.email,
name: data.name
};
}
}
Common Mistakes
- Over-engineering on first pass
- Adding features not covered by tests
- "While I'm here" additions
Phase 3: REFACTOR - Improve Quality
Purpose
Clean up the code while keeping tests green.
Actions
- Look for improvements:
- Duplication
- Poor naming
- Complex logic
- Long functions
- Make ONE change
- Run tests
- If green, continue. If red, undo.
Example
// REFACTORED version
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
class UserService {
async createUser(data: CreateUserInput): Promise<User> {
this.validateEmail(data.email);
return this.buildUser(data);
}
private validateEmail(email: string): void {
if (!EMAIL_REGEX.test(email)) {
throw new InvalidEmailError(email);
}
}
private buildUser(data: CreateUserInput): User {
return {
id: crypto.randomUUID(),
...data,
createdAt: new Date()
};
}
}
Refactoring Checklist
- Extract long methods
- Rename unclear variables/functions
- Remove duplication (DRY)
- Simplify conditionals
- Add type safety
Test Patterns
Arrange-Act-Assert (AAA)
it('should calculate discount correctly', () => {
// Arrange
const cart = new Cart();
cart.addItem({ price: 100 });
// Act
const discount = cart.calculateDiscount();
// Assert
expect(discount).toBe(10);
});
Given-When-Then (BDD)
describe('given a cart with items over $100', () => {
describe('when calculating discount', () => {
it('then should apply 10% discount', () => {
// ...
});
});
});
Coverage Commands
JavaScript/TypeScript
# Jest
npx jest --coverage
# Vitest
npx vitest run --coverage
Python
pytest --cov=src --cov-report=html
Go
go test -cover ./...
go test -coverprofile=coverage.out ./...
Anti-Patterns
1. Test After
Writing code first, tests second defeats the purpose.
2. Testing Implementation
// BAD: Testing HOW it works
expect(service.internalMethod).toHaveBeenCalled();
// GOOD: Testing WHAT it does
expect(result).toEqual(expectedOutput);
3. Brittle Tests
// BAD: Breaks if order changes
expect(users[0].name).toBe('Alice');
// GOOD: Resilient assertion
expect(users).toContainEqual(expect.objectContaining({ name: 'Alice' }));
4. No Refactoring
Skipping refactor phase leads to technical debt.
Quick Reference
| Phase | Question to Answer | Action |
|---|---|---|
| RED | What should it do? | Write failing test |
| GREEN | Does it work? | Write minimal code |
| REFACTOR | Is it clean? | Improve structure |
Integration
This skill works with:
- conductor-context: For project-specific coverage targets
- code-styleguides: For language-specific test patterns
Score
Total Score
75/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
✓説明文
100文字以上の説明がある
+10
○人気
GitHub Stars 100以上
0/15
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon


