외부활동/우아한테크코스 [프리코스]

[우아한테크코스 8기] 프리코스 오픈미션 최종회고

softmoca__ 2025. 11. 26. 22:04
목차

시작하며

6주간 진행한 프리코스의 마지막 미션을 3주간 TDD라는 주제에 대해 목표를 잡고 도전하며 엄청난 몰입으로 많은 성장을 할수 있어 너무 행복했다. 프리코스 여러 미션들 그중에서 이번 오픈미션이 아니었다면 나는 아마 TDD에 대해 현재와 같은 경험을 얻지 못하며 주먹구구식으로 TDD를 접하고 진정한 가치들을 미처 들여다보지 못한 채 넘겼을 것 같다.
프리코스를 통해 TDD에 대한 궁금증과 관심이 생겼고 그 덕분에 2권의 TDD 도서를 정독하고 나만의 언어로 정리하며 다시금 소중한 지난 프리코스 미션들을 TDD로 다시 돌아보며 많은 시야와 깨달음을 얻을 수 있었다.

오픈 미션을 진행하며 늘 하루 10시간 이상 오픈 미션을 위해 끙끙대며 기상 직후, 식사 도중, 운동 도중, 대중 교통 속 제 모든 일상이 오픈미션에 대한 생각으로 가득 차 있는걸 종종 인지하며 스스로 너무 대견하고 온전한 몰입 그자체로 너무 행복 했다.
그간 프리코스 미션들과 마찬가지로 여느 코딩테스트 시험과 달리  “정답을 찾는 것”이 아닌 “성장을 경험하는 과정”들을 매번 기록하고 회고하는 과정들이 너무 아름다웠다.
우아한테크코스 운영진분들 덕분에 무료로 너무 좋은 교육 프로그램을 통해 즐기며 폭발적인 성장과 너무 아름다운 감정들을 느낄 수 있는 기회를 주셔서 늘 너무 감사한 마음이 든다 

 

“선정 배경- 왜 TDD 였는가, 반복되는 실패와 고민에서 찾은 질문”

그간 프리코스 미션들을 진행하며 테스트는 “정답을 검증 하고 버그를 잡을수 있는 도구”라고 생각하며 테스트 코드를 작성했었다. 하지만 3주차 미션에서 보너스 번호 매칭 로직 버그를 제출 전날 발견하였고, 디버깅을 하며 원인 파악과 수정에 많은 시간이 소요되었다.
아주 높은 몰입을 통해 미션을 진행하며 최대한 테스트 코드를 잘 작성하기 위해 노력을 했지만 뒤늦게 버그를 발견해서 많이 놀랐었다. 이후 회고를 진행하며, 내가 집중을 하지 않았나 ? 테스트 코드를 꼼꼼히 작성하지 않았나 ? 요구 사항을 꼼꼼히 확인하지 않았나 ? 등등 확인하는 시간을 가졌다.
그 과정에서 요구 사항 분석 및 이해와 꼼꼼한 테스트코드 작성 보다 압도적으로  ‘객체지향적인 설계’에만 많은 고민을 했었던 것이 원인이었다는 결론에 도달했다.
객체지향적인 설계를 고민하고 이에 대한 학습을 하는 과정에서 분명 엄청난 성장을 했었지만, 가장 기본인 ‘문제 없이 돌아가야 한다’는 소프트웨어의 본질을 잠시 놓치고 있었다.
이 경험을 통해 설계의 아름다움 이전에,요구사항을 정확히 이해하고, 그 요구사항을 끝까지 책임지는 테스트가 먼저라는 사실을 다시 한 번 깊게 깨닫게 되었다.

또한 2주차 미션 과정 중 Service 계층을 만들었다가 제거 하는 리팩토링과정에서  "이 코드를 지워도 괜찮을까?" "이렇게 바꾸면 다른 곳이 깨지지 않을까?" 와 같은 많은 고민들과 함께 상당한 혼란스러움을 경험했다.
테스트 코드가 있었지만, 구현 후에 작성한 테스트였기에 구조 변경 시 함께 무너졌다.
테스트를 수정하고 또 깨지는 악순환 속에서, 결국 리팩토링을 중도에 포기하거나 최소한으로만 진행했었다.
또한 1~3주차 매 미션 마다 여러 설계 방향에 대한 고민이 끊이지 않았다. "검증 로직은 어디에 두어야 하나?", “콜백 패턴과 전략 패턴을 적용해야 하나?”, “출력의 책임과 DTO는 ?“, “이건 단위 테스트인가? 통합테스트인가 ?”, "값 객체로 만들어야 하나, 원시값 포장으로 충분한가?", "Stream API를 사용하려면 getter를 추가해야 하는데, 이게 맞나?" 구현을 먼저 하다 보니 "이미 만들어진 구조에 맞춰 테스트를 억지로 끼워 맞추는" 상황이 반복되었다.
테스트 작성이 어렵다는 것은 설계가 좋지 않다는 신호였지만, 지금 생각해보니 그저 학습과정이라서 힘든것이라 이런 신호를 미처 인식하지 못던것 같다.

무엇보다  지난 7기 프리코스 4주차 편의점 미션의 회고 과정도 떠올랐다.
당시에도 최종 제출 시 1개의 테스트가 실패하여, 디버깅을 하며 원인 파악과 수많은 수정을 시도했다. 
단 하나의 실패한 테스트를 해결하기 위해 모든 코드를 뒤엎으며, 기존에 지켜왔던 프로그래밍 요구사항들을 모두 무너뜨리고 말았다.

이런 경험들은 나에게 중요한 질문을 남겼다.
 "왜 테스트를 작성했는데도 이런 일이 반복되는 걸까?"
 "테스트 코드가 있으면 안전할 줄 알았는데, 왜 리팩토링할 때 무너졌을까?" 
그리고 테스트 작성 시기의 중요성에 대해 깨달게 되었다.
구현을 먼저 하고 테스트를 나중에 작성했기에 요구사항 누락을 뒤늦게 발견했고, 구현에 의존적인 테스트가 되어 리팩토링 시 깨졌으며, 테스트가 설계를 개선하기보다 구현을 정당화하는 도구가 되어있었다.
즉,  테스트는 단순히 정답을 검증하는 수단이 아니라, 요구사항을 발견하고 설계를 이끄는 도구임을 인식하게 되었다.

 

 

목표 - 오해를 깨고 진실을 체득하기”

단순히 TDD를 “한 번 적용해 보는 경험”에서 끝내는 것이 아니라, 프리코스를 진행하며 내가 테스트 코드에 대해 가지고 있던 여러 오해들을 바로잡고, 실제 코드와 시행착오 속에서 설계와 테스트의 진짜 가치를 몸으로 체득하는 것이 이번 오픈 미션의 가장 큰 목표였다.

첫 번째 목표는 요구사항 탐색 도구로서의 TDD를 체험하는 것이었다.
Red → Green → Refactor 사이클을 반복하며, 테스트를 먼저 작성하는 과정에서 자연스럽게 “이 기능은 어떤 경우까지 책임져야 하지?”, “이건 예외 상황인가, 정상 흐름인가?” 같은 질문을 스스로에게 던지도록 만들고 싶었다.
특히 구현 전에 실패하는 테스트를 먼저 작성함으로써, 평소라면 지나쳤을 예외 케이스를 미리 발견하고, 작은 단위로 검증을 쌓아가며 큰 실수를 사전에 차단하는 경험을 직접 느끼고자 했다.

 

두 번째 목표는 리팩토링 안전망으로서의 TDD를 체험하는 것이었다.
그동안의 프리코스에서는 “구현 → 테스트” 순서로 진행하다 보니, 리팩토링을 시도할 때마다 “이 코드를 지워도 괜찮을까?”, “여길 바꾸면 어디가 또 깨질까?”라는 불안이 항상 따라다녔다.
이번에는 테스트를 먼저 두고 구현을 쌓아 올린 뒤, TDD 사이클 안에서 구조를 과감하게 고쳐 보며 “이렇게 바꿔도 될까?” → “테스트 통과! 안전하다.” 라는 흐름을 실제로 체감해 보고 싶었다. 테스트가 더 이상 수정의 족쇄가 아니라, 구조 변경을 뒷받침해 주는 안전망이 되는지 확인하고, 그 덕분에 리팩토링을 회피하지 않고 오히려 적극적으로 시도할 수 있는지 검증해 보고자 했다.

 

세 번째 목표는 설계 고민을 TDD로 풀어보는 것이었다.
그동안 “검증 로직은 어디에 둘까?”, “DTO 변환은 어디 책임이지?”, “이건 VO로 빼야 하나?” 같은 설계 고민들을 머릿속에서만 굴리다가, 이미 만들어진 구조에 맞춰 테스트를 억지로 끼워 넣는 경우가 많았다.
이번 오픈 미션에서는 반대로, “이 객체를 실제로 어떻게 사용하게 될까?” 를 먼저 고민하며 테스트를 작성하고, 그 테스트가 자연스럽게 설계를 이끌어 가는 경험을 목표로 삼았다.

 

테스트하기 어려운 코드를 설계의 냄새로 받아들이고, “기존 억지 테스트”가 아니라 “정말 필요하고 자연스러운 테스트”가 무엇인지 구분해 보며, 테스트하기 쉬운 코드 = 좋은 설계라는 말을 내 코드 기준으로 검증해 보고자 했다.

 

 

마지막 네 번째 목표는 매 미션마다 TDD 사고 과정과 경험들을 기록으로 남기는 것이었다.
TDD가 실제로 어떤 순간에 도움을 주었는지, 어떤 선택에서 갈등했고 왜 그 방향을 택했는지, 아쉬운 점이 있다면 무엇이었는지를 매번 정리하면서, 단순한 결과물이 아니라 사고 과정 전체를 학습 자산으로 축적하고 싶었다.
특히 “잘했다 못했다”의 평가보다는, “무엇을 느꼈는지”, “다음에는 어떻게 할지”에 집중해 회고함으로써, 이번 오픈 미션이 끝나도 계속해서 되돌아볼 수 있는 나만의 TDD 학습 기록을 남기고자 했다.

 

실행계획

처음 세운 나의 계획은 아래와 같다.

1주차

  1. 3일간 ‘테스트주도 개발 시작하기’ 도서 정독 및 정리
  2. 테스트주도 개발 시작하기 도서 정리 후 나만의 언어로 TDD에 대해 정리하기
  3. 3일간 1주차 문자열 계산기 미션 TDD로 다시 진행
  4. 1주차 문자열 계산기 미션 TDD로 진행하며 기록한 목표 4 경험들 정리
  5. 3일간 2주차 자동차 경주 미션 TDD로 다시 진행
  6. 2주차 자동차 경주 미션 TDD로 진행하며 기록한 목표 4 경험들 정리
  7. 1주차 회고 및 계획 변동사항 확인
  8. 추가 참고 도서 ‘테스트 주도개발 TDD 실천법과 도구 정리’ 볼 지 고려

2주차

  1. 3일간 2주차 로또 미션 TDD로 다시 진행
  2. 3주차 로또 미션 TDD로 진행하며 기록한 목표 4 경험들 정리
  3. 3일간 7기 4주차 편의점 미션 TDD로 다시 진행
  4. 4주차 자동차 경주 미션 TDD로 진행하며 기록한 목표 4 경험들 정리
  5. 2주차 회고 및 진행 사항 확인 및 계획 변동

여러 코드 리뷰를 진행하며 기본적으로 TDD는 시간이 오래 걸린다는 것을 알고 있어 너무 타이트하게 계획을 세우진 않았다.

이 점을 미리 고려한점이 지금와서 보니 정말 신의 한수 였다.

비교적 간단한 1,2주차 미션의 경우에도 기존 계획보다 훨씬 오래 걸렸으며, 무엇보다 2차에 너무 많이 방황해서 이미 계획이 딜레이 되었지만 시간이 남을 경우 보려고 한 도서를 읽어 본 점이 꽤나 치명적이었다. 하지만 너무나 필요한 과정이었고 이러한 과정들이 내가 그저 대충 미션을 대하지 않았다는 증거이기도해서 뿌듯했다.

그간 프리코스 코드 리뷰를 하며 많은분들이 TDD는 경험 한 뒤 시간이 너무 오래걸리고 현실적으로 자신과는 맞지 않아 앞으로는 쓰지 않을 것이라는 결론을 지은것 봤다.

아마 나 또한 단 1주의 시간동안 하나의 미션에 TDD를 적용하며 접했다면 같은 결론에 도달했을 것 같다. 하지만 그간 나의 프리코스 기간동안의 경험들과  3주간 2권의 도서와 4번의 미션들에 TDD를 적용을 거친 나는 전혀 다른 결론에 도달했다.

나에게는 정말 신세계이며 이런게 패러다임인가 싶은 느낌이다. 특히 최대한 노력을 했지만 놓치며 아쉬워하는 경험들이 이런 방법론과 시스템으로 보완이 된다는 점이 정말 쇼킹 그자체다 !

물론 늘 그랬듯 앞으로의 개발인생을 살며 언제든 이러한 나의 기치관이 달라질 수 있을것 같다. 하지만 현재의 나는 너무 좋은 무기와 장비를 얻게되어 그저 행복할 뿐이다.

 

“요구사항 탐색 도구로서의 TDD”

오픈 미션을 진행하며 가장 인상 깊은 경험은 요구 사항 탬색 도구로서의 TDD의 힘이었다.

문자열 계산기 미션을 TDD로 다시 진행하며 첫 번째 목표를 바로 체험할 수 있었다.
단위 테스트는 모두 통과했지만 ApplicationTest가 실패했을 때, 원인을 파악하며 초기 요구사항을 제대로 파악하지 못했음을 발견했다. Java 리터럴의 개행문자와 콘솔 입력의 역슬래시+n의 차이를 대충 이해하고 있었던 것이 문제였다. 이미 3번째 접하는 미션이었지만 매번 같은 문제에 대해 조금이 나마 더 깊은 이해를 가질수 있다는 점이 너무 신기했고, TDD를 접해서 순간 너무너무 행복했다.
이 경험을 통해 TDD 사이클을 반복하는 과정 자체가 요구사항을 놓치지 않도록 계속해서 되묻게 만든다는 것을 느꼈다. 단순히 "읽고 이해하는 것"이 아니라 시스템적으로, 강제적으로 이해하게 만드는 것이었다.
로또 미션에서는 Rank 설계 과정에서 보너스 번호 로직의 숨은 버그를 사전에 발견했다. 처음에는 "보너스가 없으면 탈락"이라는 잘못된 가정을 하고 구현하려 했지만, 테스트를 통해 "1등, 3등, 4등, 5등은 보너스와 무관하게 결정된다"는 실제 요구사항을 정확히 이해하게 되었다. 3주차에서 겪었던 동일한 유형의 버그를 이번에는 사전에 차단할 수 있었다.
지난 3주차 미션을 진행할 때도 분명 가능한 온힘을 다해 최대한 집중하고 몰입을 했었지만, 내가 짠 테스트 코드가 부실했다는 사실에 꽤나 많이 나 자신에게 실망을 했었다.  하지만 TDD를 통해 시스템적으로 반강제적으로 테스트 코드, 나아가 리팩토링을 통한 프로덕션 코드 자체가 자연스럽게  스트레스 없이 단단해 질 수 있다는 점이 너무 충격적이었고, 너무 신나게 오픈미션을 진행할수 있었다.


편의점 미션에서는 프로모션 계산 로직의 복잡한 케이스들을 테스트 작성 과정에서 사전에 발견할 수 있었다. "2+1 프로모션이면 3개 구매 시 1개 무료"는 명확했지만, "5개 구매하면?"이라는 질문에서 막혔다. 테스트를 먼저 작성하며 고민하니, 5개 구매 시에는 3개만 프로모션이 적용되고 2개는 정가라는 "세트 단위 계산" 규칙을 발견했다. 프로모션 재고가 7개인데 10개를 구매하면 어떻게 되는지, 멤버십 할인은 프로모션 적용 금액에도 적용되는지 등 숨어 있던 요구사항들이 테스트 작성 과정에서 하나씩 드러났다.
"이렇게 동작하겠지"라는 추측이 아니라 "실제로 확인해보자"는 태도가 필요하다는 것을 깨달은 점이 가장 인상 깊었다. TDD는 막연한 가정을 줄이고, 확실한 검증 위에서 구현하도록 훈련시키는 도구였다.
작년에 놓쳤던 마지막 1개의 테스트를 다시 확인해 볼순 없지만 이렇게나 꼼꼼히 요구사항을 정확히 분석할 수 있다는 점에서 TDD의 힘에 너무 놀랐다. 그저 태생적으로의 꼼꼼함과 집중이 아닌 개발론적으로 이렇게나 요구사항을 꼼꼼히 이해하고 개발할수 있다는 점이 너무신기했다.

 

“마치며 - 오해를 깨고 진실을 체득했는지 되돌아보기”

요구사항 탐색 도구로서의 TDD는 확실히 체험했다. 테스트를 먼저 작성하며 요구사항을 자연스럽게 탐색하고, 누락된 로직을 사전에 발견하는 경험을 했다. 3주차에서 겪었던 보너스 번호 버그와 같은 실수를 이번에는 사전에 차단할 수 있었다.
리팩토링 안전망으로서의 TDD도 충분히 경험했다. "구현 후 테스트"와 "테스트 후 구현"의 차이를 몸소 느꼈고, 테스트가 수정의 족쇄가 아닌 구조 변경의 안전망이 된다는 것을 확인했다. 무엇보다 심리적 안정감이 주는 효과가 생각보다 훨씬 커서 스트레스가 비교적 훨씬 적은 상태로 리팩토링을 고민하는 점이 너무 충격적이었다.
설계 피드백 도구로서의 TDD 역시 체감했다. "어떻게 사용할 것인가"를 먼저 고민하며 테스트를 작성하니 설계가 자연스럽게 도출되었고, 테스트하기 어려운 코드는 설계 문제의 신호라는 것을 직접 경험했다.
예상치 못한 발견도 있었다. 모든 테스트가 같은 가치를 가지지 않는다는 것, TDD와 OOP 학습은 때로 충돌할 수 있다는 것, 완벽한 설계는 없으며 상황에 맞는 균형점을 찾는 것이 중요하다는 것을 배웠다.

3주차 소감문에서 "테스트를 먼저 작성하면 인터페이스 설계부터 하게 되어 사용하기 편한 API가 자연스럽게 나올 것 같다", "예외 상황과 버그를 미리 필요한 시점에 고민하며 더 견고한 코드를 작성할 수 있을 것 같다"고도 작성을 했었는데 실제로 이러한 장점을 온전히 느끼고 경험했다.

무엇보다 중요한 것은, 이 모든 깨달음이 이론이 아니라 실제 코드를 작성하며 겪은 경험에서 나왔다는 점이다. 책에서 읽은 내용은 쉽게 잊히지만, 직접 좌절하고 해결하며 얻은 깨달음은 오래 남는 다는걸 알아 더욱 뿌듯했다.
프리코스 전체를 돌아보면, 1주차는 객체지향적 사고의 시작이었고, 2주차는 설계와 테스트의 본질을 탐구하는 시간이었으며, 3주차는 제거하는 리팩토링과 개념의 본질을 이해하는 시간이었다. 그리고 오픈미션은 그동안의 모든 고민과 실패를 TDD라는 렌즈로 다시 바라보며 통합하는 시간이었다.

정확히 1년 전 7기 프리코스에서는 예외 처리와 히든 케이스를 찾는 것에만 집중했었다. 지금의 나는 설계 원칙과 패턴, 테스트 전략을 고민하고, 더 나아가 TDD를 통해 요구사항과 설계를 탐색하는 방법을 배웠다. 이 변화가 나에게는 가장 큰 성장의 증거이자 앞으로 달려갈 수 있는 큰 동력이다.

마지막으로 너무 좋은 교육 프로그램을 무상으로 제공해주시고, 이렇게 성장할 수 있는 기회를 주셔서 정말 감사합니다 운영진 선생님분들. 프리코스가 끝나더라도 이번에 체득한 TDD의 가치를 잊지 않고, 앞으로의 개발 여정에서 계속 실천하겠습니다 !
본 교육 과정에서의 페어프로그래밍을 통해 TDD를 하는 그 날을 고대하며, 최종 코딩테스트를 위해 노력 하고 있겠습니다. 다시 한번 감사합니다 :)