
프리코스에서 서비스 개발로 확장하기까지
프리코스 1~3주차는 TDD를 체득하기 위해 고민하고 반복했던 시간이었다. 값 객체(Value Object), 일급 컬렉션, 검증 책임 분리, 안전한 리팩터링 구조 등을 익히며 테스트가 코드 품질에 어떤 영향을 주는지 확인할 수 있었다.
그 과정에서 자연스럽게 더 큰 규모의 프로젝트에 이를 적용해보고 싶다는 생각이 들었다. 그래서 4~5주차 미션을 받자마자 평소에 구상해두었던 ‘라멘 맛집 탐색 서비스 — 라오타’를 선택했다. 라멘 인증샷이 여러 플랫폼에 흩어져 있다는 문제에서 출발한 이 프로젝트는 회원, 가게, 메뉴, 인증샷, 찜, 방문 기록 등 실질적인 상호작용이 존재하고 기능 확장 가능성도 충분했다. 1~3주차에서 익힌 객체 중심 설계와 TDD를 실전에서 검증하기에 적합한 환경이었다.
또한 이번 프로젝트에서는 두 가지 도전 목표를 추가했다.
- 스프링 환경에서 테스트 우선 개발 흐름을 유지하는 것
- 온프레미스 환경에서 배포, 실행, 자동화를 직접 경험하는 것
그동안은 클라우드 기반 배포에 익숙했지만, 로컬 테스트 서버를 직접 구축하고 CI와 연결해보는 경험은 꼭 해보고 싶었다.
사전 조사 — TDD와 개발 방식에 대한 근거 쌓기
라오타를 만들기 전, TDD가 실제 서비스 개발에서도 유효한지 확인하기 위해 여러 자료를 찾아보았다.
- 스프링 환경에서 TDD를 적용하는 방식
- Outside-In 접근 흐름
- REST-Assured를 이용한 API 테스트 자동화
- 온프레미스 환경 구성 사례
특히 아래 자료들이 방향을 잡는 데 도움이 됐다.
- 최범균의 객체지향 설계와 테스트 관련 강의
- 어라운드 허브 스튜디오: 테스트 코드 적용하기 (JUnit, TDD)https://youtu.be/SFVWo0Z5Ppo?si=ztplehvbj4Xgpn48
- REST-Assured 공식 문서https://github.com/rest-assured/rest-assured
- 밸로그: 미니PC로 홈서버 구축 도전해보자https://velog.io/@today-is-first/%EB%AF%B8%EB%8B%88-PC%EB%A1%9C-%ED%99%88%EC%84%9C%EB%B2%84-%EA%B5%AC%EC%B6%95-%EB%8F%84%EC%A0%84%ED%95%B4%EB%B3%B4%EC%9E%90
이 조사는 단순한 ‘흥미’가 아니라 프로젝트 설계 방식을 선택하는 데 근거가 되어주었다.
설계 과정 — 객체의 책임과 테스트 가능성
라오타의 도메인은 콘솔 기반 과제와 달리 훨씬 복잡했다. 그래서 설계에서 가장 신경 쓴 부분은 다음 두 가지였다.
- 객체가 무엇을 책임져야 하는가
- 그 책임을 테스트 가능한 형태로 유지할 수 있는가
값 객체와 일급 컬렉션의 실전 적용
주소, 메뉴 이름, 태그, 인증샷 목록 등은 단순한 데이터가 아니라 의미를 가진 값이었다. 이를 VO와 일급 컬렉션으로 감싸며 제약과 무결성을 객체 스스로 보장하도록 만들었다.
장점은 명확했다.
- 검증 로직이 흩어지지 않음
- 도메인 모델이 타입 안정성을 가짐
- 테스트하기 쉬운 구조가 됨
JPA 매핑이 길어지는 단점도 있었지만, 기능 확장과 변경이 반복되면서 이 구조가 갖는 가치를 확실히 체감했다.
Inside-Out과 Outside-In의 균형 찾기
초기에는 도메인부터 구현하는 Inside-Out 방식을 따랐다. 그러나 실제 API 개발이 시작되자 사용자 흐름이 더 앞서 있다는 것을 깨달았다.
그래서 다음과 같은 방식으로 조정했다.
- 도메인 규칙과 상태 변화: Inside-Out
- API 흐름, 응답 모델, 사용자 경험: Outside-In
이 균형을 찾는 과정이 설계와 테스트 모두에 큰 도움이 되었다.
전략 패턴의 실전 필요성
전략 패턴은 처음부터 노린 게 아니었다.
랜덤, 파일 업로드, 로그인 방식 같은 변경 가능 영역이 테스트를 방해했기 때문이다.
그래서 전략을 다음과 같이 적용했다.
- 외부 의존 기능을 인터페이스로 분리
- 테스트는 인터페이스 기반으로 진행
- 구현체는 이후에 교체 가능
이 방식은 서비스 로직이 비대해지는 것을 막고 확장성과 테스트 용이성을 모두 확보할 수 있었다.
테스트 설계 — 로컬에서 E2E까지
라오타의 테스트 구조는 단계적으로 확장되었다.
1) 로컬 단위 테스트
- JUnit + AssertJ
- Given–When–Then 유지
- 핵심 도메인 로직 검증
2) 슬라이스 테스트
- @WebMvcTest, @DataJpaTest 적용
- JSON 직렬화, 매핑, 컨트롤러 계층 검증
- Mockito any() 매칭 문제 경험
3) Testcontainers 기반 통합 테스트
- MySQL과의 차이를 확인하기 위해 도입
- 실제 환경과 동일한 DB에서 검증
4) 온프레미스 기반 E2E 자동화
- 직접 서버를 구성
- GitHub Actions self-hosted runner 활용
- 포트포워딩/방화벽/DHCP 문제 해결
특히 공유기 제약으로 외부 접근이 막혔을 때, runner를 통해 문제를 우회한 경험은 클라우드 자동화가 당연하지 않다는 사실을 깨닫게 했다.
전체적인 배움 — “구현”이 아니라 “설계와 근거”
이번 미션의 가장 큰 수확은 개발의 무게 중심이 바뀌었다는 점이다.
- 정답을 찾아가는 방식 → 스스로 설계하는 방식
- 테스트는 검증 도구 → 설계와 흐름을 통제하는 장치
- 배포는 부가 요소 → 서비스의 필수 조건
또한 기술 외적으로도 의미 있는 변화가 있었다.
- 비교 대신 관찰
- 속도보다 지속
- 결과보다 과정
SQLD 시험, 졸업작품, 스터디까지 병행하며 균형을 유지하려고 했던 태도 역시 성장의 일부였다.
앞으로 더 다뤄보고 싶은 주제
이번 경험을 기반으로 더 탐구해보고 싶은 영역은 다음과 같다.
- CQRS 적용 및 조회 모델 최적화
- 운영 환경 관찰 가능성(Observability)
- 로그 수집
- 메트릭
- 장애 감지
- 슬로우 쿼리 분석
- 학습 리듬과 태도 유지
라오타를 계속 발전시키며 이 부분들을 실험해볼 계획이다.
'외부활동 > 우아한테크코스 8기 프리코스' 카테고리의 다른 글
| 우아한테크코스 프리코스 8기 3주차 회고 (0) | 2025.11.24 |
|---|---|
| 우아한테크코스 프리코스 8기 2주차 회고 (0) | 2025.11.01 |
| 우아한테크코스 프리코스 8기 1주차 회고 (0) | 2025.10.20 |
