TDD Red-Green-Refactor Cycle
Red Phase: Write Failing Test
- •Express intended behavior as test first
- •Test only one behavior at a time
- •Must verify failure by running test (compilation errors count as failures)
kotlin
// Kotest DescribeSpec example
class CalculatorTest : DescribeSpec({
describe("Calculator") {
it("두 숫자를 더한다") {
val calculator = Calculator()
calculator.add(2, 3) shouldBe 5
}
}
})
Verify failure message matches intent. Unexpected failure reasons indicate test issues.
Green Phase: Make Test Pass
- •Write minimal code to pass the test
- •Hardcoding, duplication, messy code allowed
- •Goal is only green bar
kotlin
class Calculator {
fun add(a: Int, b: Int): Int = 5 // Hardcoding OK
}
"Working code" first, "clean code" next.
Refactor Phase: Improve Code
- •Keep tests passing while improving
- •Remove duplication, improve naming, apply patterns
- •Must re-run tests after refactoring
- •No new features - structural improvements only
kotlin
class Calculator {
fun add(a: Int, b: Int): Int = a + b // Generalize
}
Cycle Rules
- •No production code without test
- •No production code changes without failing test
- •Commit after passing tests (keep commits small)
- •No new features during refactoring
- •Minimize test changes during refactoring
Checklist
Red
- • Test verifies single behavior?
- • Verified failure by running test?
- • Failure message as intended?
Green
- • Passed with simplest approach?
- • Test is green?
Refactor
- • Tests still green?
- • Duplication removed?
- • Names reveal intent?
- • No new features added?