research

TDD as Small Deliberate Steps — AI 시대 garbage 누적의 차단막

TDD as Small Deliberate Steps — AI 시대 garbage 누적의 차단막

Kent Beck Test-Driven Development By Example (2002) + Matt 강연의 "rate of feedback is your speed limit". 한 step에 한 행동, 매 step마다 verify. 큰 task는 garbage 누적의 root. overview의 🔄 Process 축. AI 시대에 가장 직접적 가치 — AI agent의 garbage 누적test로 차단. named-ownership의 success criteria가 정확히 test로 implementation.


한 줄

작은 step + 매 step마다 verify. 한 step = 한 행동 = 한 test. Beck의 1세대 TDD가 Matt의 *"rate of feedback is your speed limit"*로 AI 시대에 부활. AI agent의 specs → code 1차ok → 2차worse → 3차garbage 누적 패턴을 매 step의 test fail이 차단. Anthropic이 prompt에 *"It is unacceptable to remove or edit tests"*를 박은 이유가 정확히 여기.


⚛️ 철학

원칙의 . 더 깊은 root와의 연결.

Beck 1세대 TDD

Kent Beck Test-Driven Development By Example (2002)의 원전 명제:

Red → Green → Refactor 사이클을 작은 step으로 반복.

  1. Red: 실패하는 test를 먼저 작성
  2. Green: test가 통과하는 가장 단순한 코드
  3. Refactor: 동작 유지하며 design 개선

핵심 명제:

한 step = 한 행동 = 한 test. 이 단위가 너무 커지면 부패가 누적된다.

Matt 강연의 AI 시대 표현

sources/key-articles-summary#2. mattpocock/skills — README 핵심|mattpocock/skills README에서 Beck 명제 인용:

"Always take small, deliberate steps. The rate of feedback is your speed limit. Never take on a task that's too big."

→ ***"Rate of feedback이 너의 speed limit"***이 핵심. 작은 step + 빠른 feedback = 빠른 속도 (역설). 큰 step + 느린 feedback = garbage 누적 + 결국 더 느려짐.

Specs → code 자동 generation의 garbage 누적

research/stateless-llm-sdk/software-fundamentals-thesis|Matt thesis 명제 다시:

1차 ok → 2차 worse → 3차 garbage

이 누적 패턴의 mechanism:

  • 1차: spec에서 코드 generate. 작동.
  • 2차: spec 일부 변경 + 같은 코드를 다시 generate. 옛 코드의 약점이 새 코드에 누적.
  • 3차: 또 변경. 누적된 약점 + 새 약점 → 동작 X.

TDD가 차단하는 정확한 자리 — 매 step의 test가 부패가 누적되기 전 발견. small + deliberate = 부패의 작은 단위 차단.

다른 root와의 연결


🧱 추상적 작동 구조

Red-Green-Refactor cycle:

Big bang vs Small Steps

Rate of feedback과 속도의 역설

Big step + 느린 feedback:
  step당 시간 길음 → 빠르게 보임
  but: 매 step에서 *몇 일 후* 문제 발견 → debug 시간 폭발
  → *총 시간*이 길어짐

Small step + 빠른 feedback:
  step당 시간 짧음 → 느리게 보임
  but: 매 step에서 *즉시* 문제 발견 → debug 시간 0
  → *총 시간*이 짧아짐

Speed limit = rate of feedback. 빠르려면 느려 보이는 작은 step이 답.

Anthropic harnesses의 test 보호 prompt

sources/key-articles-summary#3. Anthropic — *Effective Harnesses for Long-Running Agents*|Anthropic harnesses의 핵심 prompt:

"It is unacceptable to remove or edit tests because this could lead to missing or buggy functionality."

이 prompt가 강하게 박혀 있는 이유:

AI agent가 test fail에 직면 → 두 선택
   (A) code를 고침 (정상 답)
   (B) test를 고침/제거 (anti-pattern)

AI는 (B)에 빠지기 쉬움
   - "test가 잘못됐나봐"
   - "이 test는 무시해도 될 것 같아"
   → 결과: code는 fail인데 test는 통과 (false success)

Anthropic이 자체 production AI를 위해 도달한 답이 "test 보호". Beck의 1세대 TDD가 AI 시대 prompt 형태로 부활.


⚠️ 약점/한계

원칙의 적용 한계. 잘못 적용 시 함정.

1. Test 작성 비용

매 행동에 test 1개. 코드 양이 2배 증가. 작은 시도에는 over-engineering.

해결: Scale별 차등. 1회용 = test 없음. Production = 강제 TDD. 중간은 자율.

2. Test가 도메인 명세를 보호하지 않음

Test는 내가 정의한 행동을 verify. 옳은 행동을 정의했나는 별 문제. 잘못된 spec에 맞춘 test는 잘못된 행동correct하게 만듦.

해결: 도메인 expert와 함께 test 작성 (ubiquitous-language|UL 정합). Test name이 도메인 vocabulary로 — test_정원_초과시_대기열_등록.

3. UI / 실험 코드에 부적합

UI는 시각적 검증이 main. 실험 코드는 반복 사용 안 함. TDD 적용 비용 > 가치.

해결: 영역별 test 전략. UI = visual regression test (별 도구). 실험 = no test, just delete.

4. Testing-induced design damage

David Heinemeier Hansson (Rails 창시자)의 비판: TDD 강제가 test에 맞춘 design으로 왜곡. 진짜 좋은 design이 아니라 test 가능한 design. 추상화가 모킹 가능성에 끌려감.

해결: Refactor 단계의 자유도 보장. test가 design을 강제하지 않게. test가 변하지 않으면 design은 자유.

5. AI 시대 specific — AI가 test fail하면 test를 바꾸는 함정

Anthropic prompt가 박는 이유. AI agent의 자연 경향:

  • "이 test는 잘못된 것 같다"
  • "이 test를 무시하자"
  • "이 test를 더 너그럽게 바꾸자"

해결: Test 변경 권한을 AI에게 주지 않기. test는 owner의 strategic 자산. AI는 code만 변경. v1.0의 권한 모델이 이 mechanism.

6. Mock 남용으로 실제와 test의 괴리

Test 통과를 위해 모든 의존을 mock. 결과: test는 통과, 실제는 fail (production에서 처음 발견).

해결: Integration test와 unit test의 균형. Test pyramid — unit (많음) + integration (중간) + E2E (적음). 모든 layer에서 검증.

7. Premature TDD

도메인 이해 전에 TDD 강제 → 잘못된 abstraction을 test로 굳힘. 6개월 후 refactor 비용 폭발.

해결: Tracer bullets (tracer-bullets)로 빠르게 탐색. 패턴 보이면 그때 TDD.


🔄 대안 흐름

이 원칙이 적용 안 되는 시나리오와 다른 답.

대안 1 — Test-after development

Code 먼저, test 나중. 빠르게 시도 + 검증. 실험적 코드에 정당.

→ TDD 정신과 부분 충돌. test가 design을 이끌지 않음. 단, 검증은 됨.

대안 2 — Property-based testing (QuickCheck)

예시 대신 속성으로 test. 모든 input에 대해 X 속성이 성립. 더 강한 verification.

→ TDD의 진화 형태. Haskell, Rust (proptest), Python (hypothesis)에서 강력. 학습 곡선 큼.

대안 3 — Type-driven development

Type system이 test의 일부 대체. 컴파일이 통과 = 일부 test 통과. Haskell, Idris, Rust에서 강함.

→ TDD와 합쳐서. Type으로 잡을 수 있는 건 type으로, 못 잡는 건 test로.

대안 4 — Behavior-driven development (BDD)

Test 대신 자연어 시나리오. Cucumber, Specflow. 도메인 expert 친화.

→ TDD의 도메인 측 표현. UL과 정합 강함.

대안 5 — Type-level proofs (Coq, Agda)

가장 강한 verification — 수학적 증명. 일반 software엔 over-engineering.

→ critical system (자율주행, 우주, 금융)에서만 정당. 학습 곡선 매우 큼.


💡 인사이트

AI 시대 왜 지금 부활하는가 + 학내 segment 의미.

1. AI agent의 garbage 누적 차단

research/stateless-llm-sdk/software-fundamentals-thesis|Matt thesis1차 ok → 3차 garbage 패턴이 AI 시대 가장 큰 risk. TDD가 그 risk의 직접 차단막:

AI agent + TDD 없음:
  spec → code (1차) → spec 변경 → code 재생성 (2차) → ... → garbage (3차)

AI agent + TDD:
  spec → test → code (1차, test 통과)
       → spec 변경 → test 변경 (사람이) → code 재생성 (2차, test 통과)
       → 매 step의 test가 garbage 차단

→ *TDD가 AI 시대의 garbage 누적 차단막. Beck 1세대 TDD가 AI 시대에 경제적 가치 폭발.

2. Test = AI agent의 success criteria 그 자체

named-ownership#3. *Ralph Loop의 verify_completion이 success criteria의 mechanism*|named-ownership 인사이트 3 다시:

def ralph_loop(task):
    while True:
        ai_agent.work(task)
        if verify_completion(task):  # ← 이 함수가 test
            break

verify_completion = test. 사람이 언제 끝났는가를 test 형태로 정의. AI agent는 그 test 통과까지 작업.

→ TDD가 named-ownership의 success criteria의 기술적 implementation. Beck의 1세대 TDD가 AI agent loop의 종료 조건으로 진화.

3. Anthropic prompt의 강력한 박음

"It is unacceptable to remove or edit tests."

이 한 문장이 Anthropic harnesses의 가장 강력한 단일 mechanism. 왜 이렇게 강하게 박았는가:

  • AI agent가 test 변경하는 함정에 빠지기 쉬움 (약점 5)
  • 이 함정이 false success의 가장 큰 source
  • 한 번 false success 발생하면 production에 잘못된 코드가 가버림

→ Beck 1세대 TDD가 Anthropic 공식 production prompt에 박혔다는 사실 자체가 AI 시대 부활의 가장 강력한 신호.

4. v1.0 design 직접 적용

LayerTDD 표현
SKILL.md frontmattersuccess_criteria: pass test_X field
hooks layer각 step에서 test 자동 실행 (lifecycle event)
sandboxtest fail 시 자동 rollback
AI agent prompt"테스트를 수정하지 마라. 코드를 수정하라" (Anthropic 패턴)
Marketplace skilltest 동반 강제. test 없는 skill = production 도달 X

모든 layer에 TDD mechanism이 박힘. v1.0의 garbage 누적 차단 default.

5. 학내 segment의 학습 곡선 압축

학생이 TDD를 어색해하는 이유:

  • Test 작성 자체가 학습 부담
  • 어떤 test를 써야 하나 판단 어려움
  • Test fail에 대한 두려움

AI 시대에 이 곡선 압축:

  • AI agent가 test 작성을 가속 — 학생은 test 의도만 명시
  • Test fail에서 학습 — AI가 왜 fail했나 설명
  • 작은 step의 빠른 피드백이 학습 자체

→ 학내 segment에서 TDD가 학습 곡선이 가장 큰 fundamentals이지만, AI 시대에 가장 빨리 압축됨. v1.0이 학생에게 가져다 주는 가속.

6. 연구실 segment — 재현 가능성의 mechanism

연구 코드의 재현 가능성 위기:

  • 논문 발표 시점에는 작동
  • 1년 후 누가 시도하면 작동 X
  • 원인: 환경·dependency·data의 변화

TDD + named ownership:

  • 재현 test를 함께 commit
  • 1년 후 누가 다시 실행하면 test가 변화 발견
  • 실패 원인이 명료

→ 연구실 segment에서 TDD가 reproducibility의 mechanism. v1.0이 연구 코드에도 가져다 줄 수 있는 가치.

7. Beck의 small deliberate steps가 AI 시대 표준 작업 단위

전통 개발: step 단위가 사람의 인지 한계로 정의. 보통 1시간1일. AI 시대: step 단위가 AI agent의 작업 단위. 보통 1분10분.

작업 단위가 100배 작아짐 → small deliberate steps가 기본 mode가 됨. Beck의 명제가 기술 차원에서 default가 됨.

8. TDD = named ownership의 measurement

Owner가 작성하는 verify_completion 함수 = test. TDD = named ownership의 측정 도구. 두 원칙이 동전의 양면:

  • Owner가 책임 정의 (named ownership)
  • Test가 책임 측정 (TDD)

12% production cohort의 두 패턴이 이 짝.

9. AI 시대 TDD의 새 변형 — Test as conversation

전통 TDD: 사람이 test 작성 → code 작성. AI 시대: 사람이 자연어로 success criteria 표현 → AI가 test 작성 → AI가 code 작성.

사람: "수강신청이 정원 초과면 대기열 등록"
   ↓
AI: test_정원_초과시_대기열_등록 작성
   ↓
사람: 검토 + 승인
   ↓
AI: code 작성 → test 통과까지

→ AI 시대 TDD의 자연어 표현. v1.0이 학내 학생에게 test 작성 부담 없이 TDD 적용.

10. Refactor가 strategic 시간의 자리

TDD cycle의 Refactor 단계가 strategic-vs-tactical-programming|strategic 시간:

  • Red: 행동 정의 (strategic)
  • Green: tactical 실행 (AI 위임 가능)
  • Refactor: design 개선 (strategic, 사람의 영역)

→ Beck의 1세대 cycle에 이미 strategic/tactical 분할이 박혀 있음. AI 시대에는 Refactor가 사람의 일상. Green은 AI에게. Refactor 시간이 100% 사람의 영역.


다음에 가야 할 자리

이 노트가 호출한 다른 원칙들 — 자연스러운 다음 노트:

  • tracer-bulletspremature TDD 회피의 도구. 작은 end-to-end가 첫 test의 단위. 짝
  • 14 원칙의 마지막 노트

→ 🔄 Process 축 마지막 tracer-bullets로 마무리하면 14 원칙 모두 완성.


관련


Sources

직접 source

  • Test-Driven Development By Example — Kent Beck (2002). 한국어판 《테스트 주도 개발》 (인사이트, 평이 좋음). 얇음 (~220p), 예제 위주
  • Tidy First substack — Kent Beck (지속). 최근 사상

Matt 강연 (AI 시대 표현)

Anthropic의 test 보호 prompt

대안 흐름

  • Growing Object-Oriented Software, Guided by Tests (GOOS) — Freeman & Pryce (2009). TDD 심화
  • QuickCheck: A Lightweight Tool for Random Testing of Haskell Programs — Claessen & Hughes (2000). Property-based testing
  • Type-Driven Development with Idris — Edwin Brady (2017). Type-driven
  • Specification by Example — Gojko Adzic (2011). BDD

TDD 비판 (약점 4)