一键导入
tdd-workflow
Complete Test-Driven Development workflow with red-green-refactor cycle
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Complete Test-Driven Development workflow with red-green-refactor cycle
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Web accessibility audit workflow for WCAG compliance
RESTful and GraphQL API design patterns and best practices
Structured code review workflow for quality and consistency
Safe database migration workflow with zero-downtime strategies
Git release workflow with semantic versioning and changelogs
Comprehensive performance audit workflow for web applications
| name | tdd-workflow |
| description | Complete Test-Driven Development workflow with red-green-refactor cycle |
| license | MIT |
Use this skill when implementing features using Test-Driven Development methodology.
┌──────────────────────────────────────────────────────────┐
│ │
│ 🔴 RED → 🟢 GREEN → 🔵 REFACTOR │
│ Write test Make pass Improve code │
│ that fails (minimal) (keep green) │
│ │
│ ↺ Repeat │
└──────────────────────────────────────────────────────────┘
Understand the requirement
Write the simplest test case first
describe('calculateDiscount', () => {
it('should return 0 for orders under $50', () => {
expect(calculateDiscount(30)).toBe(0);
});
});
Run the test - it MUST fail
npm test -- calculateDiscount
Write the minimal code to pass
function calculateDiscount(orderTotal: number): number {
return 0;
}
Run the test - it MUST pass
npm test -- calculateDiscount
Don't over-engineer - Only write enough code to pass the current test
Add the next test case and repeat the cycle:
it('should return 10% for orders $50-$100', () => {
expect(calculateDiscount(75)).toBe(7.5);
});
it('should apply discount to premium users', () => {
// Arrange
const user = createUser({ isPremium: true });
const order = createOrder({ total: 100 });
// Act
const result = applyDiscount(user, order);
// Assert
expect(result.total).toBe(90);
expect(result.discountApplied).toBe(10);
});
// Format: should_[expected behavior]_when_[condition]
it('should return empty array when no items match filter', () => {});
it('should throw ValidationError when email is invalid', () => {});
it('should retry 3 times when API returns 503', () => {});
Create a password validator that checks:
// Step 1: RED - First test
describe('validatePassword', () => {
it('should reject passwords shorter than 8 characters', () => {
expect(validatePassword('Short1')).toEqual({
valid: false,
errors: ['Password must be at least 8 characters'],
});
});
});
// Step 2: GREEN - Minimal implementation
function validatePassword(password: string) {
const errors: string[] = [];
if (password.length < 8) {
errors.push('Password must be at least 8 characters');
}
return { valid: errors.length === 0, errors };
}
// Step 3: RED - Next test
it('should reject passwords without uppercase', () => {
expect(validatePassword('lowercase1')).toEqual({
valid: false,
errors: ['Password must contain an uppercase letter'],
});
});
// Step 4: GREEN - Add uppercase check
function validatePassword(password: string) {
const errors: string[] = [];
if (password.length < 8) {
errors.push('Password must be at least 8 characters');
}
if (!/[A-Z]/.test(password)) {
errors.push('Password must contain an uppercase letter');
}
return { valid: errors.length === 0, errors };
}
// Step 5: RED - Test for number requirement
it('should reject passwords without numbers', () => {
expect(validatePassword('NoNumbers')).toEqual({
valid: false,
errors: ['Password must contain a number'],
});
});
// Step 6: GREEN - Add number check
function validatePassword(password: string) {
const errors: string[] = [];
if (password.length < 8) {
errors.push('Password must be at least 8 characters');
}
if (!/[A-Z]/.test(password)) {
errors.push('Password must contain an uppercase letter');
}
if (!/[0-9]/.test(password)) {
errors.push('Password must contain a number');
}
return { valid: errors.length === 0, errors };
}
// Step 7: REFACTOR - Clean up
const PASSWORD_RULES = [
{ test: (p: string) => p.length >= 8, message: 'Password must be at least 8 characters' },
{ test: (p: string) => /[A-Z]/.test(p), message: 'Password must contain an uppercase letter' },
{ test: (p: string) => /[0-9]/.test(p), message: 'Password must contain a number' },
];
function validatePassword(password: string) {
const errors = PASSWORD_RULES
.filter(rule => !rule.test(password))
.map(rule => rule.message);
return { valid: errors.length === 0, errors };
}
// Step 8: RED - Happy path test
it('should accept valid passwords', () => {
expect(validatePassword('ValidPass1')).toEqual({
valid: true,
errors: [],
});
});
// Already passes! ✅
# Run tests in watch mode
npm test -- --watch
# Run specific test file
npm test -- validatePassword
# Run with coverage
npm test -- --coverage
# Run and update snapshots
npm test -- --updateSnapshot
In these cases, write tests after, but still write them.