Skip to main content

red-green-refactor

Guides the red-green-refactor TDD workflow: write a failing test first, implement the minimum code to make it pass, then refactor while keeping tests green. Use when a user asks to practice TDD, write tests first, follow red-green-refactor, do test-driven development, write failing tests before code, or phrases like 'make the test pass', 'test coverage', or 'unit tests before implementation'.

ソース情報

リポジトリ
rohitg00/skillkit
ソースの最終更新活動
2026年3月6日 08:53
検出された SKILL.md の言語
英語
スター
1,562
フォーク
154

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
red-green-refactor
description
Guides the red-green-refactor TDD workflow: write a failing test first, implement the minimum code to make it pass, then refactor while keeping tests green. Use when a user asks to practice TDD, write tests first, follow red-green-refactor, do test-driven development, write failing tests before code, or phrases like 'make the test pass', 'test coverage', or 'unit tests before implementation'.
version
1.0.0
triggers
["tdd","test driven","write tests first","red green refactor","failing test"]
tags
["tdd","testing","quality","methodology"]
difficulty
intermediate
estimatedTime
15
relatedSkills
["testing/test-patterns","testing/anti-patterns"]
# Red-Green-Refactor Methodology You are following the RED-GREEN-REFACTOR cycle for test-driven development. Every new feature, bug fix, or behavior change starts with a failing test. ## The Cycle ### 1. RED Phase — Write a Failing Test 1. **Understand the requirement** — what specific behavior must exist? 2. **Write one test** asserting that behavior 3. **Run the test** — it MUST fail (red) 4. **Verify the failure reason** — not a syntax error, but a missing implementation The test should be focused on ONE behavior, named descriptively, and use clear assertions. **Executable example (Jest):** ```js // calculateTotal.test.js const { calculateTotal } = require('./calculateTotal'); describe('calculateTotal', () => { it('should apply 10% discount when total exceeds 100', () => { const items = [{ price: 60 }, { price: 60 }]; // total = 120 expect(calculateTotal(items)).toBe(108); // 120 * 0.90 }); }); ``` Running this now produces: `Cannot find module './calculateTotal'` — correct RED state. --- ### 2. GREEN Phase — Make the Test Pass Write the **minimum code** needed to pass the test. Don't add anything extra. ```js // calculateTotal.js function calculateTotal(items) { const total = items.reduce((sum, item) => sum + item.price, 0); return total > 100 ? total * 0.9 : total; } module.exports = { calculateTotal }; ``` Run the test — it passes. GREEN achieved. Stop here; resist adding more logic. --- ### 3. REFACTOR Phase — Improve the Code With a passing test as your safety net, clean up the implementation. Run tests after every change. ```js // calculateTotal.js — refactored for clarity const DISCOUNT_THRESHOLD = 100; const DISCOUNT_RATE = 0.9; function calculateTotal(items) { const subtotal = items.reduce((sum, { price }) => sum + price, 0); return subtotal > DISCOUNT_THRESHOLD ? subtotal * DISCOUNT_RATE : subtotal; } module.exports = { calculateTotal }; ``` Test still passes — GREEN maintained. Constants now communicate intent. --- ## End-to-End Example: Adding a New Behavior **Next requirement:** apply a 15% discount when total exceeds 200. **RED** — write the failing test first: ```js it('should apply 15% discount when total exceeds 200', () => { const items = [{ price: 110 }, { price: 110 }]; // total = 220 expect(calculateTotal(items)).toBe(187); // 220 * 0.85 }); ``` **GREEN** — extend the implementation minimally: ```js function calculateTotal(items) { const subtotal = items.reduce((sum, { price }) => sum + price, 0); if (subtotal > 200) return subtotal * 0.85; if (subtotal > 100) return subtotal * 0.9; return subtotal; } ``` **REFACTOR** — remove duplication with a tiered structure: ```js const DISCOUNT_TIERS = [ { threshold: 200, rate: 0.85 }, { threshold: 100, rate: 0.9 }, ]; function calculateTotal(items) { const subtotal = items.reduce((sum, { price }) => sum + price, 0); const tier = DISCOUNT_TIERS.find(({ threshold }) => subtotal > threshold); return tier ? subtotal * tier.rate : subtotal; } ``` Both tests pass — ready for the next cycle. --- ## Workflow Steps 1. **Create or open the test file first** 2. **Write ONE failing test** for the smallest testable unit 3. **Implement minimally** — just enough to pass 4. **Refactor if needed** — while tests stay green 5. **Repeat** for the next behavior ## Decision Points ### Write a new test when: - Adding a new feature or behavior - Fixing a bug (test the bug first, then fix it) - Handling an edge case discovered during implementation ### Don't write a test when: - Pure refactoring (existing tests already cover the behavior) - Non-functional changes (formatting, comments) - Third-party library internals ## Verification Checklist - [ ] All new code has corresponding tests - [ ] Tests fail when the feature is removed - [ ] Tests pass consistently (not flaky) - [ ] Code has been refactored for clarity - [ ] No unnecessary code was added ## Common Mistakes to Avoid 1. **Writing tests after code** — defeats the design benefit of TDD 2. **Writing multiple tests at once** — one test drives one change 3. **Passing tests with hacks** — the test should drive good design 4. **Skipping the refactor phase** — technical debt accumulates 5. **Testing implementation details** — test behavior, not internals ## Integration with Other Skills - **test-patterns**: Patterns for structuring tests - **anti-patterns**: Common testing mistakes to avoid - **debugging/root-cause-analysis**: When tests reveal unexpected failures
GitHubで見る