항해플러스 프론트엔드 5기 | 3챕터 회고

들어가며

벌써 항해가 8주차가 흘렀다. 3챕터의 큰 주제는 테스트코드였다. 테스트 코드는 실무에서 cypress로 e2e테스트만 해봤는데, 이번 챕터 과제를 하며 유닛테스트, 통합테스트, e2e 모두를 아우를 수 있는 테스트를 경험해볼 수 있었다. 그만큼 힘들었지만(?) 뿌듯했던 시간을 보낼 수 있게 해주었던 과제였던 것 같다.

과제를 하며 배운 점

1. TDD를 처음 경험해보다

반복 일정 기능을 구현하며 유닛 테스트, 통합 테스트, E2E 테스트까지 단계별로 작성해보았. 실무에서는 다양한 테스트를 경험해본 적이 없었는데, 이번 과제를 통해 테스트에 대한 전반적인 것을 익힐 수 있었. 특히, 반복 일정 기능 추가를 위해 TDD를 경험해볼 수 있어서 좋았다.

실패 => 성공 => 리팩토링이라는 TDD프로세스를 이해해보기 위해, 실제 테스트를 먼저 작성하고 실패하게 만든 뒤, 이를 통과시키기 위해 코드를 작성하는 과정을 거쳐 보았다.

다만 아직 TDD 방식이 익숙하지 않다 보니, 테스트를 통과시키기 위해 곧바로 기능 구현에 집중하게 되는 경우도 있었고, 테스트 중심 개발의 흐름을 유지하는 것이 생각보다 쉽지 않다는 점도 느꼈다. 이 과정을 통해 TDD의 장점뿐 아니라 현실적인 어려움과 한계도 함께 체감할 수 있었던 경험이었다.

2. 골고루 섞인 테스트 전략이 필요하다고 느꼈다

테스트 전략을 공부하며 테스트 피라미드와 테스트 트로피라는 개념을 알게 되었다. 이번 과제의 대상이었던 일정 관리 애플리케이션은 사용자의 일정 생성, 반복, 수정, 삭제 등 전체 흐름의 안정성이 중요한 서비스라고 판단했다.
따라서 비즈니스 로직의 정확성을 검증하는 단위 테스트, 상태 변화와 컴포넌트 동작을 확인하는 통합 테스트, 실제 사용자 시나리오를 점검하는 E2E 테스트 모두가 필요하다고 느꼈다.

단순히 피라미드처럼 단위 테스트를 많게, 트로피처럼 통합 테스트를 많게 구성하기보다는, 이번 과제에서는 팀과 논의 후 일정관리 캘린더 특성에 맞춰 단위, 통합, E2E 테스트를 균형 있게 배치해보는 전략을 선택했었다.

테스트가 애플리케이션을 더 탄탄하게 만들어준다는 걸 느꼈다. 테스트를 작성하면서 기능에 대한 요구사항을 더 명확히 정의할 수 있었던 경험이었다. 단위 테스트부터 통합 테스트, E2E 테스트까지 단계별로 쌓아가다 보니, 애플리케이션 전체가 점점 더 단단해지는 느낌이 들었다. 특히 테스트를 작성할 때, 먼저 "어떤 상황을 테스트하고 싶은가?"를 시나리오 단위로 정리한 후, 그에 필요한 유틸 함수를 구현하는 방식으로 접근했었다.

예를 들어,

“매달 31일 반복 일정을 생성했을 때, 31일이 없는 달은 건너뛴다”

라는 시나리오를 먼저 정한 뒤, 이를 검증할 수 있는 generateMonthlyRepeats 함수를 구현하는 식으로 개발을 진행했다. 이런 방식은 단순히 테스트를 위한 테스트가 아니라, 기능 요구사항과 코드 구현을 동시에 설계해나가는 과정처럼 느껴졌다.
또한 반복 일정 기능을 구현하면서 네이버 캘린더의 동작 방식을 참고해봤는데, 실제 서비스에서 어떻게 처리하고 있는지를 직접 사용해보니 테스트 시나리오를 구성하는 데 큰 도움이 되었다.

3. 테스트는 문제 해결보다 문제 발견에 가까웠다

테스트를 먼저 작성하면서, 놓치기 쉬운 예외 케이스들을 사전에 고려하게 되었다는 점도 인상 깊었다. 예를 들어 매월 반복 일정 생성 시 2월처럼 31일이 없는 달, 윤년 같은 특수 조건들을 테스트 시나리오를 정리하며 자연스럽게 다루게 되었다. 이처럼 테스트는 기능 검증 도구이자, 문제를 미리 발견하게 해주는 설계 가이드 역할도 해준다고 느꼈다.

또한 테스트 시나리오를 기반으로 유틸 함수를 설계하다 보니, 기능 구현 시 책임 범위를 명확히 구분하고 구조화하는 데도 도움이 되었다. 테스트와 기능이 서로 영향을 주고받는 경험이 신선했고 많은 것을 배울 수 있었다.

4. 통합테스트를 위해 MSW로 API 요청을 가로채는 법을 알게 되었다

MSW는 mock service worker로 브라우저나 테스트 환경에서 가짜 API서버처럼 동작해주는 도구이다. 실제 백엔드 없이도 API 동작을 검증할 수 있게 해준다.

예를 들어, 테스트 코드에서 saveEvent()를 호출하면 내부적으로 fetch('/api/events-list', ...) 같은 API 요청이 발생한다고 하자. 실제 백엔드가 없거나 테스트 중에는 이런 요청을 실제 서버에 보내면 안되니까, MSW가 대신 응답을 흉내내주게 된다.

5. E2E 테스트를 위해 playwright를 써봤는데, 신세계였다

요즘 e2e테스트 대세라는 playwright를 이제야 써보다니,, 넘 신세계였다. 개인적으로 엄청 빠르다고 느꼈고, 병렬처리가 가능한게 너무 편했다..! 앞으로 실무에서 e2e테스트를 하게 되면 Cypress가 아니라 Playwright를 사용할 것 같다.

과제를 하며 아쉬웠던 점

1. e2e 테스트 시 codegen을 써볼걸

다른 동료가 e2e 테스트 시 codegen을 써서 테스트를 했다고 했다. 직접 codegen을 이용해 e2e테스트를 하는 걸 봤는데.. 이렇게 간편하다니 ㅠㅠ난 이것도 모르고 삽질도 많이했다 ^^..

2. 정말 필요한 테스트인지 인지하며 작성해볼걸

e2e는 전반적인 프로세스를 테스트하며 사용자를 위한 것이고 유닛과 통합 테스트는 개발자를 위해서 필요한 테스트라는 것을 다시 한번 인지하게 되었다. 그리고 내가 작성한 e2e 테스트가 정말 사용자 관점에서 필요한 테스트일까? 아닐 수도 있지 않을까라는 생각도 들었다. 의미있는 테스트인지 생각하며 테스트를 하는게 정말 중요함을 다시한번 깨달았다.

마치며

항해플러스를 하며 벅찰 때도 있지만, 내가 안해본 것들을 해볼 수 있어서 정말 감사한 시간이다. 다른 동료들이 개발하는 것도 볼 수 있어서 많이 배운다. 아 이렇게도 개발할 수도 있구나,, 시야가 확장된다. 항해 플러스를 추천하냐고 물어보면, 시간적 여유가 있다면 난 꼭 추천하고 싶다. 그만큼 시간을 들여 투자해야 얻어가는 것도 많은 것 같다.

추천 코드를 입력하면 20만원이 할인된다고 한다. 항해 플러스 관심많으시면 20만원 할인도 받아가세요~~!

내 추천 코드 : BKkA3U


Written by@chloee
기록하는 것을 좋아하는 프론트엔드 개발자👩🏻‍💻

GitHubLinkedIn