d3ro-voice/docs/tdd-red/02-meaningful-vs-meaningless-red.md
Yun Chan c3ddd36c6f
Some checks failed
deploy-site / deploy (push) Failing after 40s
docs: record the 1.1.0 release and add the infrastructure map
Release notes for 1.1.0 were split between an Unreleased section and the
version section, so the published notes would have omitted the update-feed
and desktop changes. Everything shipping in this version now sits under one
`## [1.1.0]` heading.

`docs/map/` becomes the entry point for what infrastructure exists per
platform and how far each feature is developed, with a documented update
protocol so feature work and this map do not drift apart again. The release
guide now states that installer binaries live in the update feed rather than
the repository.
2026-09-16 23:27:52 +09:00

6.8 KiB

02 · 의미 있는 RED vs 의미 없는 RED

목적: 'RED'라는 이름 아래 흔히 섞여 있는 것들을 "행위를 정말 명세·검증하는가"라는 단일 기준으로 의미 있음/의미 없음으로 분리한다. 판정 원칙 한 줄: "이 테스트가, 구현을 고치지 않았는데 통과할 수 있는가? 통과해도 아무것도 증명하지 않는가? 그렇다면 의미 없는 RED다."


판정 축 (5 기준)

# 의미 있는 RED 는… 의미 없는 RED 는…
1 행위(behavior) 공개 인터페이스/관찰 가능한 결과 하나를 명세 내부 구현·프라이빗 메서드·호출 순서·데이터 구조 세부
2 단정(assertion) 실제 결함을 잡을 수 있는 강한 단정 단정 없음 / 상수 단정 / 커버리지만 채움
3 실패 이유 "행위 부재 또는 결함 재현" 예상된 이유로 실패 컴파일·셋업·문법·무관한 이유로 실패(그래도 빨강)
4 결정성 결정적·저비용·재현 가능, 시간/랜덤/네트워크 제어 비결정적, flaky, 외부 인프라 의존, 목으로 전부 인공화
5 의도(설계) 테스트를 쓰며 인터페이스 설계를 의도적으로 결정 테스트 목록 없이 즉흥, 구현 세부를 그대로 돌려보기

한 축이라도 "의미 없음"이면 그 RED는 빈 껍데기다. 특히 (2) 단정(3) 실패 이유가 핵심.


의미 있는 RED (KEEP) — 12가지 패턴 카탈로그

레드팀 정정: 아래 12가지는 상호배타적인 '유형'이 아니라, 5축(판정 축)을 충족하는 사례의 패턴 카탈로그다. 하나의 좋은 테스트는 여러 패턴을 동시에 충족한다(예: #1+#8+#10). "12 중 하나"라기보다 5축을 모두 충족해야 의미 있으며 12가지는 그 판정을 돕는 예시다. 특성화(#12)·회귀(#3)는 "행위 부재로 실패" 정의의 명시적 예외(레거시/결함)다.

패턴 설명 근거
1. 행위 우선 RED 한 가지 비즈니스 규칙/관찰 결과를 먼저 명세, 그 행위 없음으로 실패 Fowler, Canon TDD
2. 경계·엣지 RED 경계값(50원, 49.99원), 빈 입력, null, malformed, 오류 경로, 상태전이 Microsoft, spec-driven
3. 회귀 RED 결함을 재현(실패 이유=결함 재현) — fix 전에 실패 확인, 정의 예외 Fowler, Alderson
4. 인터페이스 설계 RED 테스트 작성 시점에 API/시그니처를 의도적으로 결정 Beck Design-in-TDD
5. 삼각측량 RED 예제를 하나씩 추가하며 일반화를 강제 (Fake→Triangulate→Obvious) TDD By Example
6. 결함-검출 잠재력 RED "구현이 미묘하게 틀려도 통과할까?"에 NO가 나오는 테스트 Microsoft, 뮤테이션
7. 외부 강제 수용 RED (AI) 인간이 쓴 보호 수용 테스트로 에이전트의 완료를 게이트 2026 TDD-Agent, TDAD, TDFlow
8. 블랙박스 RED 결과·상태변화·예외·외부 상호작용만 단정, 세부 구현 비의존 → 리팩터에 생존 fowler_test_pyramid
9. Traceable RED 요구→수용 시나리오→테스트 ID→파일 추적 가능 SDD traceability
10. 설명력 있는 RED 이름이 Withdraw_BalanceInsufficient_Throws — 실패 시 무엇이 깨졌는지 즉시 Microsoft, AAA
11. 독립 검증 RED (AI) 구현 에이전트와 분리된 검증자/모델·신선 컨텍스트가 작성 2026 권장 루프
12. 특성화 (레거시 전처리) 기존 동작을 승인/캡처해 리팩터 안전망으로 — RED 정의의 예외: 즉시 통과(행위 없음이 아님) Characterization/Approval

의미 없는 RED (DELETE) — 10가지

유형 증상 왜 나쁜가 근거
1. 가짜 RED (fake) expect(true).toBe(true), 단정 없음 커버리지만 높이고 결함 0 검출 survey, Microsoft
2. 사소한 RED (trivial) getter·언어기능·프레임워크 반복 테스트 결함-검출 가치 없음 survey
3. 구현-세부 RED 프라이빗 메서드·내부 호출순서·데이터 구조 단정 리팩터 때마다 깨져 재작성 → 리팩터를 막음 fowler_test_pyramid
4. 인공 시스템 RED 전부 목/스텁으로 인공화, 실제 통합 경계 미검증 실제 결함을 놓침, DHH의 'test-induced damage' Is TDD Dead
5. 복붙 기대값 RED 계산 결과를 그대로 기대값에 복붙 이중검증 파괴, 자신의 버그를 '정답'으로 고정 Beck Canon TDD
6. 커버리지-채움 RED 단정 삭제/축소로 위장 초록, %만 올리기 은탄환이 아닌 커버리지 Beck, Google
7. 의례적(all-at-once) RED (단위 계층) 테스트를 전부 먼저 쓰고 구현 — 수용·보호 계층의 사전 작성은 예외 첫 테스트가 후속 사양을 무효화하면 대량 낭비 Beck Canon TDD
8. 비결정 RED 시간·랜덤·네트워크·DB·셰어드 상태 의존 flaky → 신뢰 상실, zero-tolerance 대상 Azure WAF, Microsoft
9. 비대(broad) RED 수많은 시나리오를 전 계층에 중복 반복 유지보수 폭증, 신호 희석 Google "No more E2E"
10. 에이전트 약화 RED 테스트 삭제·스킵·비활성·광범위 목 대체·참조 없는 과잉 구현 독립 검증 붕괴, 에이전트가 지름길 (주의: #10은 '삭제 대상 테스트'가 아니라 금지 프로세스 행동 — 판정 워크플로로는 잡히지 않음) Alderson, Emily Bache/Probity

판정 워크플로 (이 테스트를 유지/삭제할까?)

1. 이름이 행위를 명세하는가?           (아니오 → 수정 또는 삭제)
2. 단정이 결함을 잡을 수 있는가?        (아니오 → 뮤테이션으로 확인 후 삭제)
3. 깨졌을 때 이유가 명확한가?          (아니오 → 세부 구현 의존 의심)
4. 구현을 고치지 않고 통과할 수 있는가? (예 → 가짜/사소, 삭제)
5. 구현 세부(프라이빗/호출순서)를 검증? (예 → 블랙박스로 재작성)
6. 결정적이고 저비용인가?             (아니오 → 하위 계층으로 이동)
7. 리팩터(행위 보존)를 견디는가?       (아니오 → 행위 단정으로 재작성)
전부 YES → 유지 (의미 있는 RED)

뮤테이션은 '판정 보조 도구' (05 §4 정책): 개별 테스트를 매번 뮤테이션으로 판정하면 비용 과다. 대신 리뷰에서 단정이 상수 교체·경계 반전을 잡는지 눈으로 검사하고, 정리(cleanup) 국면·금융/인가/안전 로직에서만 뮤테이션(변경 파일 증분)으로 확인한다. (레드팀 정정: 기존 "최종 판정기" 표현은 05와 모순 — 통일)