켄트 벡과 익스트림 프로그래밍(XP)이 어떻게 TDD, 짧은 반복, 피드백 루프를 대중화했는지—그리고 이 아이디어들이 오늘날에도 팀을 이끄는 이유를 살펴본다.

켄트 벡(Kent Beck)의 익스트림 프로그래밍(XP)은 때때로 초기 웹 시대의 유물처럼 보인다: 흥미롭고 영향력 있지만 약간 구식인 것처럼. 그러나 자주 배포하기, 사용자로부터 빠른 신호 받기, 코드를 변경하기 쉽게 유지하기 같은 현대 소프트웨어 팀의 많은 습관은 XP의 핵심 아이디어와 직접 연결된다.
이 글의 목표는 간단하다: XP가 어디서 왔는지, 무엇을 고치려 했는지, 그리고 왜 그 핵심 부분들이 지금도 유효한지 설명하는 것이다. 찬사도, 반드시 따라야 할 규칙집도 아니다. 건강한 엔지니어링 팀에서 여전히 등장하는 원칙들에 대한 실용적인 안내로 생각하라.
XP는 여러 실천법의 묶음이지만, 세 가지 주제가 반복해서 나타난다:
엔지니어, 테크 리드, 엔지니어링 매니저, 또는 개발자와 밀접히 협업하는 제품 중심 독자라면, XP는 “부수지 않고 빠르게 움직이기”가 실제로 어떻게 보일 수 있는지에 대한 공통 어휘를 제공한다.
마지막에 다음을 할 수 있어야 한다:
XP가 여전히 중요한 이유는 소프트웨어 개발을 예측의 문제로 보지 않고 학습의 문제로 보기 때문이며, 팀이 더 빨리 배울 수 있는 구체적 방법을 제공하기 때문이다.
켄트 벡은 익스트림 프로그래밍(XP)이라는 이름을 붙인 사람으로 종종 소개되고, 이후 애자일 운동 형성에 기여했다. 하지만 XP는 이론적 연습으로 시작한 것이 아니다. 특정한 고통에서 비롯된 실용적 대응이었다: 요구사항이 계속 바뀌고, 소프트웨어가 자주 깨지며, 팀은 ‘진짜’ 문제가 너무 늦게야 드러나는 상황이었다.
XP는 실제 전달 제약에서 나왔다—빡빡한 일정, 진화하는 범위, 늦게 발견되는 문제의 증가하는 비용. 팀들은 비즈니스가 무엇을 필요로 하는지 아직 결정 중인 상태에서 복잡한 시스템을 만들어야 했다. 전통적 계획은 안정성을 전제로 했다: 요구사항을 미리 모으고, 설계하고, 구현한 다음 출시 직전에 테스트한다. 그 안정성이 없을 때 계획은 무너졌다.
XP가 주로 겨냥한 적은 ‘문서’나 ‘프로세스’ 자체가 아니라—늦은 피드백이었다.
무겁고 단계별인 방법론은 학습을 지연시키는 경향이 있었다:
XP는 순서를 뒤집었다: 행동과 정보 사이의 시간을 줄였다. 그래서 TDD, 지속적 통합, 리팩토링, 페어 프로그래밍 같은 실천법이 함께 어울린다—이 모두가 피드백 루프이기 때문이다.
"익스트림"이라는 이름은 좋은 아이디어를 더 멀리 밀어붙이라는 상기였다: 더 빨리 테스트하고, 더 자주 통합하며, 계속 소통하고, 배우면서 설계를 개선하라는 것이다. XP는 가치(예: 소통, 단순성)에 의해 안내되는 실천의 집합이지, 대충 넘어가라는 허가가 아니다. 목표는 지속 가능한 속도다: 올바른 것을 만들고, 변화가 이어질 때 계속 작동하도록 유지하는 것이다.
XP는 기술적 요령의 모음이 아니다. 켄트 벡은 XP를 코드베이스가 매일 변할 때 결정을 안내하는 가치들의 집합으로 구성했다. TDD, 페어 프로그래밍, 리팩토링, 지속적 통합 같은 실천은 무엇을 보호하려는지 알 때 더 의미가 있다.
소통(Communication): "지식이 한 사람 머릿속에만 갇히지 않게". 그래서 XP는 페어 프로그래밍, 공유 코드 소유권, 작은 빈도의 체크인을 강조한다. 중요한 설계 결정은 대화와 코드에 드러나야지 개인의 머릿속 비밀 모델에 숨겨져선 안 된다.
단순성(Simplicity): "오늘 동작하는 가장 단순한 것"을 하라는 의미다. 이는 작은 릴리스와 리팩토링으로 드러난다: 지금 필요한 것을 만들고, 깔끔하게 유지하며, 실제 사용이 다음 단계를 형성하게 놔둔다.
피드백(Feedback): "빠르게 배우기"다. XP는 TDD(정확성·설계에 대한 즉각적 신호), 지속적 통합(통합 위험에 대한 빠른 신호), 정기적인 고객/팀 리뷰를 통해 피드백을 일상화한다.
용기(Courage): "불편하더라도 시스템을 개선하는 변화를 하라"는 뜻이다. 용기는 리팩토링과 죽은 코드를 지우는 것을 정상으로 만든다. 좋은 테스트와 CI는 그 용기를 합리적으로 만든다.
존중(Respect): "사람에게 지속 가능한 방식으로 일하라"는 의미다. 이는 페어링(서포트), 합리적 속도 유지, 코드 품질을 공동 책임으로 여기는 관행 뒤에 있다.
흔한 XP 선택: 만약 미래를 대비해 유연한 프레임워크를 "혹시 몰라" 만들어둘지, 아니면 지금 단순한 솔루션을 구현할지 선택할 수 있다. XP는 단순성을 선택한다: 테스트와 함께 단순한 버전을 배포하고, 진짜 두 번째 사용 사례가 생기면 리팩토링한다. 이것은 게으름이 아니라 피드백이 추측보다 낫다는 베팅이다.
XP 이전에는 테스트가 종종 프로젝트 끝 근처의 별개 단계였다. 팀은 몇 주 또는 몇 달 동안 기능을 만들고, 그다음 QA에 넘기거나 출시 직전에 대대적인 수동 "테스트 패스"를 했다. 버그는 늦게 발견되어 수정이 위험해졌고, 피드백 주기는 느렸다: 결함이 드러날 때쯤이면 코드가 이미 그 주위로 성장해 있었다.
켄트 벡이 TDD로 밀어붙인 것은 간단하지만 급진적인 습관이었다: 먼저 테스트를 쓰고, 실패를 확인한 다음, 통과시키기 위한 가장 작은 변경을 만든다. "먼저 실패하는 테스트" 규칙은 쇼가 아니다—코드가 어떻게 동작해야 하는지 명확히 하도록 강제한다.
TDD는 보통 Red–Green–Refactor로 요약된다:
total() 함수).더 깊은 변화는 테스트를 설계 피드백 도구로 대하기 시작한 것이다. 테스트를 먼저 쓰면 작은, 명확한 인터페이스로 유도되고 숨겨진 의존성이 줄어들며 변경하기 쉬운 코드가 만들어진다. XP 관점에서 TDD는 피드백 루프를 촘촘하게 했다: 몇 분마다 설계 방향이 작동하는지 배우며, 마음을 바꾸는 비용이 아직 낮을 때 배울 수 있다.
TDD는 단순히 "테스트를 더 쓰는 것"이 아니다. 사고의 순서를 바꿨다: 먼저 작은 기대를 쓰고, 그다음 그것을 만족시키는 가장 단순한 코드를 작성하고, 마지막에 정리한다. 시간이 지나면 이 습관은 영웅적인 디버깅이 아니라 꾸준하고 저극적인 진전을 이끈다.
TDD를 잘 지원하는 유닛 테스트는 몇 가지 특성을 공유한다:
도움되는 규칙: 테스트가 왜 존재하는지 빠르게 말할 수 없다면, 그 테스트는 제몫을 하지 못하는 것이다.
먼저 테스트를 쓰면 구현하기 전에 호출자의 입장이 된다. 이는 마찰이 즉시 드러나기 때문에 더 깔끔한 인터페이스로 이어지는 경우가 많다:
실제로 TDD는 사용하기 쉬운 API를 만들도록 팀을 유도한다. 그것은 단지 만들기 쉬운 API가 아니다.
두 가지 신화가 많은 실망을 낳는다:
TDD는 레거시 코드(강한 결합, 경계 없음)와 UI 중심 코드(이벤트 중심, 상태 많음, 프레임워크 접착)가 있는 곳에서 힘들다. 강제로 적용하기보다는:
이렇게 사용하면 TDD는 순수성 검사(purity test)가 아니라 실용적인 설계 피드백 도구가 된다.
XP에서의 반복은 작은 시간 박스 안에서 작업을 전달하는 것을 의미한다—완료, 검토, 학습할 수 있을 만큼 작은 배치다. 릴리스를 드문 이벤트로 다루지 않고, 전달을 빈번한 체크포인트로 다룬다: 작은 것을 만들고, 작동을 증명하고, 피드백을 받고, 다음에 무엇을 할지 결정한다.
큰 사전 계획은 몇 달 앞의 필요, 복잡성, 엣지케이스를 예측할 수 있다고 가정한다. 실제 프로젝트에서는 요구가 바뀌고, 통합에서 놀라움이 나오며, "간단한" 기능이 숨겨진 비용을 드러낸다.
짧은 반복은 틀릴 수 있는 기간을 제한해서 위험을 줄인다. 접근이 통하지 않으면 몇 달이 아니라 며칠 내에 알게 된다. 또한 이해관계자는 상태 보고서 대신 실제 가치 증분을 보게 된다.
XP의 반복 계획은 의도적으로 단순하다. 팀은 종종 사용자 스토리를 사용하고—사용자의 관점에서 가치를 짧게 설명—수용 기준을 더해 "완료"의 정의를 평이한 언어로 적는다.
좋은 스토리는 누가 무엇을 원하는지, 왜 원하는지를 답한다. 수용 기준은 관찰 가능한 동작("내가 X를 하면 시스템이 Y를 한다")을 설명해 거대한 명세서 없이 모두의 정렬을 돕는다.
일반적인 XP 주기는 주간 또는 격주다:
각 반복의 끝에 팀은 보통 다음을 검토한다:
목표는 의례가 아니라 불확실성을 정보화된 다음 단계로 바꾸는 꾸준한 리듬이다.
XP는 테스트, 페어링, 지속적 통합 같은 실천으로 자주 설명되지만, 통합 아이디어는 더 단순하다: 변화를 만들고 그것이 좋은지 아닌지를 배우는 시간을 줄이라는 것이다.
XP는 여러 피드백 채널을 쌓아놓아 길게 기다리지 않도록 한다:
예측은 비용이 크고 종종 틀린다—실제 요구와 제약은 늦게 드러난다. XP는 모든 것을 예측할 수 없음을 가정하므로 방향을 바꿀 때 비용이 아직 감당할 수 있을 때 학습하도록 최적화한다.
빠른 루프는 불확실성을 데이터로 바꾼다. 느린 루프는 불확실성을 논쟁으로 만든다.
Idea → Code → Test → Learn → Adjust → (repeat)
피드백이 며칠 또는 몇 주 걸리면 문제가 증폭된다:
XP의 "엔진"은 어떤 단일 실천이 아니라, 이러한 루프들이 서로를 강화해 작업을 정렬하고 품질을 높이며 놀라움을 작게 만드는 방식이다.
페어 프로그래밍은 흔히 "두 사람, 하나의 키보드"로 묘사되지만, XP에서 진짜 아이디어는 지속적인 리뷰다. 풀 리퀘스트를 기다리지 않고 분 단위로 피드백이 일어난다: 네이밍, 엣지 케이스, 아키텍처 선택, 그리고 변경이 가치 있는지 여부까지.
두 사람이 같은 문제에 관여하면 작은 실수가 비용이 적을 때 잡힌다. 네비게이터는 누락된 널 체크, 불명확한 메서드 이름, 위험한 의존성을 발견해 버그 리포트가 되기 전에 잡는다.
동시에 페어링은 컨텍스트를 퍼뜨린다. 코드베이스는 개인의 영토처럼 느껴지지 않는다. 지식이 실시간으로 공유되면 팀은 "어떻게 작동하는지 아는 한 사람"에 의존하지 않고 온보딩이 덜 보물찾기가 된다.
피드백 루프가 즉시이기 때문에 결함이 나중 단계로 많이 빠져나가지 않는 경우가 많다. 설계도 개선된다: 복잡한 접근을 소리내어 설명해야 할 때 정당화하기 어려워진다. 결정을 서술하는 행위는 더 단순한 설계, 더 작은 함수, 더 명확한 경계를 드러내는 경향이 있다.
드라이버/네비게이터: 한 사람이 코드를 쓰고 다른 사람은 리뷰, 앞을 생각하고 질문한다. 역할을 규칙적으로 바꾼다.
로테이팅 페어: 파트너를 매일 또는 스토리별로 바꿔 지식 사일로를 방지한다.
시간 박스 세션: 60–90분 동안 페어링 후 휴식하거나 작업 전환. 집중을 유지하고 소진을 줄인다.
리팩토링은 소프트웨어의 동작을 바꾸지 않으면서 내부 구조를 변화시키는 관행이다. XP에서는 가끔 하는 정리 날이 아니라, 기능 개발과 함께 작은 단계로 일상적으로 수행하는 작업이었다.
XP는 요구가 바뀔 것이라 가정했고, 변경에 대응하려면 코드를 변경하기 쉽게 유지하는 것이 최선의 방법이라고 봤다. 리팩토링은 명명 혼동, 얽힌 의존성, 복사-붙여넣기 로직의 점진적 축적인 "설계 붕괴"를 막아 다음 변경을 더 빠르고 덜 위험하게 만든다.
리팩토링은 안전망이 있을 때만 편하다. TDD는 빠르게 반복 가능한 테스트 스위트를 만들어 리팩토링 중 실수로 동작이 바뀌었는지 알려준다. 테스트가 그린 상태라면 자신 있게 이름을 바꾸고, 재구성하고, 단순화할 수 있다. 실패하면 무엇을 망가뜨렸는지 빠르게 알 수 있다.
리팩토링은 기교가 아니라 명확성과 유연성을 위한 것이다:
두 가지 실수가 반복된다:
지속적 통합(CI)은 XP의 아이디어로 간단한 목표가 있다: 자주 병합해서 문제가 작을 때 드러나게 하라. 각자가 며칠(또는 몇 주)씩 격리되어 기능을 만들고 나서야 서로 맞지 않음을 발견하는 대신, 팀은 소프트웨어를 여러 번에 걸쳐 안전하게 통합할 수 있는 상태로 유지한다.
XP는 통합을 피드백의 한 형태로 본다. 모든 병합은 실용적인 질문에 대답한다: 우리가 실수로 뭔가를 망가뜨렸는가? 우리의 변경이 다른 사람의 변경과 여전히 작동하는가? 그 대답이 "아니오"일 때, 그 사실을 몇 분 내에 알기를 원한다.
빌드 파이프라인은 코드 변경 시마다 실행되는 반복 가능한 체크리스트다:
비기술적 이해관계자에게도 가치는 분명하다: 놀라운 장애가 줄고, 데모가 부드러워지고, 막판 소동이 줄어든다.
CI가 잘 작동하면 팀은 작은 배치를 더 자신 있게 배포할 수 있다. 그 자신감은 행동을 바꾼다: 사람들은 개선을 더 자주 시도하고, 안전하게 리팩토링하며, 변경을 쌓아두지 않고 점진적으로 가치를 전달한다.
오늘날의 CI는 보안 스캔, 스타일 검사, 성능 스모크 테스트 같은 더 풍부한 자동 검사를 포함하고, 트렁크 기반 개발(trunk-based development) 같은 워크플로우를 사용해 변경을 작게 유지하고 빠르게 통합한다. 핵심은 단일한 "정답"을 따르는 것이 아니라 피드백을 빠르게 하고 통합을 일상으로 만드는 것이다.
XP는 규율이 명확하기 때문에 강한 의견을 끌어모은다. 그게 오해되기 쉬운 이유이기도 하다.
사람들은 종종 "XP는 너무 엄격하다" 또는 "TDD는 속도를 늦춘다"고 말한다. 둘 다 일시적으로 사실일 수 있다.
XP 실천은 의도적으로 마찰을 추가한다: 먼저 테스트를 쓰기, 페어링, 지속적 통합은 "그냥 코딩"보다 느리게 느껴진다. 그러나 그 마찰은 이후 더 큰 세금(불명확한 요구, 재작업, 취약한 코드, 긴 디버깅 주기)을 방지하려고 만들어진 것이다. 진짜 질문은 오늘의 속도가 아니라 다음 달에도 계속 배포할 수 있느냐이다.
XP는 요구가 불확실하고 학습이 핵심 업무일 때 빛을 발한다: 초기 제품, 복잡한 도메인, 진화하는 고객 요구, 아이디어와 실제 피드백 사이의 시간을 줄이려는 팀. 작은 반복과 촘촘한 피드백 루프는 틀렸을 때의 비용을 줄인다.
규제가 심하거나 많은 종속성이 있거나 전문가가 많은 팀 같은 제약이 큰 작업에서는 조정이 필요할 수 있다. XP는 순수함을 요구하지 않는다. 무엇이 피드백을 주는지, 무엇이 문제를 숨기는지에 대해 정직하면 된다.
가장 큰 실패는 "XP가 작동하지 않았다"가 아니라:
한 가지 루프를 골라 강화하라:
하나의 루프가 안정되면 다음을 더하라. XP는 시스템이지만 한 번에 모두 도입할 필요는 없다.
XP는 페어링, TDD, 리팩토링 같은 특정 실천으로 기억되지만, 더 큰 유산은 문화다: 품질과 학습을 프로젝트 끝이 아니라 일상적 작업으로 보는 팀 문화.
지금 팀들이 애자일, 데브옵스, 지속적 딜리버리, 제품 탐색이라 부르는 많은 것들이 XP의 핵심 움직임을 반영한다:
팀이 "XP"라고 부르지 않을 때에도, 트렁크 기반 개발, CI 파이프라인, 기능 플래그, 가벼운 실험, 빈번한 고객 접촉 같은 동일한 패턴을 보게 될 것이다.
XP가 여전히 유효하게 느껴지는 이유 중 하나는 그 학습 루프가 현대 도구와도 잘 맞기 때문이다. 제품 아이디어를 실험할 때 Koder.ai 같은 도구는 반복 주기를 더 압축한다: 채팅으로 기능을 설명하면 작동하는 웹 앱(React)이나 백엔드(Go + PostgreSQL)를 생성하고, 실제 사용을 바탕으로 다음 스토리를 정제할 수 있다.
XP 친화적인 부분은 "마법 같은 코드 생성"이 아니라 배치를 작고 되돌릴 수 있게 유지하는 능력이다. 예를 들어 Koder.ai의 planning mode는 구현 전에 의도를 명확히 하는 데 도움을 주고(수용 기준을 쓰는 것과 유사), 스냅샷/롤백은 리팩토링이나 위험한 변경을 대규모 재작성으로 만들지 않고도 시도할 수 있게 한다.
XP는 팀을 다음으로 유도한다:
더 탐구하고 싶다면 /blog의 다른 에세이를 읽어보거나, /pricing에서 가벼운 도입 계획이 어떻게 보일지 확인해보라.