공부 및 일상기록

[WIL] 프론트엔드에서 테스트코드 본문

개발/React

[WIL] 프론트엔드에서 테스트코드

낚시하고싶어요 2025. 8. 30. 13:28

항해99 플러스가 7주차에 접어들면서 테스트코드에 대한 과제를 받게 되었다.

난이도는 easy, medium, hard가 있었는데, 나는 2년차 프론트엔드 개발자지만 한번도 실무에서 테스트코드를 경험해본적이 없어서 무난하게 medium 과제를 선택했다.

 

사실 프론트엔드에서 테스트코드는 어떻게 작성하는것인지 아예 무지했기때문에 걱정도 많았지만 친절하게 예시가 주어져있어서 어렵지 않았다.

hook에 대한 테스트코드
유닛 테스트 코드

위 처럼 미리 어떤것들을 테스트할지 정해주셨고, 이 과정을 통해 테스트 코드와 친해지는 계기를 갖게 되었다.

 

그럼 이제 내가 어떤것들을 느꼈는지 한번 보겠다.

배운 점

  • 테스트 코드 작성 경험
    이번 과제는 프론트엔드에서 테스트 코드를 어떻게 작성하고 활용할 수 있는지 전반적으로 경험할 수 있었다. 순수 유틸 함수에 대한 유닛 테스트부터, React 훅, 컴포넌트, 그리고 통합 테스트까지 직접 작성해보면서 테스트가 어떤 수준에서 어떻게 역할을 하는지 감을 익혔다.
    특히 msw로 API를 목킹하고, server.use()로 엔드포인트별 성공/실패 케이스를 정의하는 흐름을 체득했다. 이를 통해 프론트엔드 테스트도 단순히 UI 스냅샷에 그치지 않고, 비즈니스 로직과 네트워크 레이어까지 신뢰도를 확보할 수 있다는 걸 알게 되었다.
  • Provider와 Mocking의 역할
    • SnackbarProvider, ThemeProvider 같은 컨텍스트 프로바이더가 왜 필요한지 이해했다. 실제 UI 동작과 유사한 환경을 제공함으로써, 통합 테스트에서 React Portal로 열린 Select 옵션 같은 외부 DOM 요소도 정상적으로 탐색·클릭할 수 있었다.
    • useSnackbar 훅을 직접 목킹하면서 실제 UI를 띄우지 않아도 함수 호출 여부나 메시지를 검증할 수 있는 방식을 배웠다.
  • 시간 고정의 중요성
    setupTests.ts에서 시간을 고정시켜 모든 테스트가 동일한 기준을 쓰도록 한 부분이 특히 인상 깊었다. 이렇게 하지 않으면 실제 실행 시점이나 타임존 차이로 인해 불필요한 테스트 실패가 발생할 수 있음을 알았다.

고민한 점

  • 테스트 중복 vs 케이스 다양성
    같은 내부 동작을 검증하는 테스트를 서로 다른 설명으로 두 번 작성하는 게 맞을지 고민했다. 예를 들어 “월의 경계에 있는 이벤트 필터링”과 “월간 뷰의 이벤트 반환”은 사실상 같은 결과를 내는데, 이를 하나로 줄일지 아니면 경계 케이스를 더 다양하게 넣어야 할지 명확히 판단하기 어려웠다.
  • 통합 테스트의 범위
    통합 테스트에서 어디까지 사용자 관점으로 시뮬레이션해야 하는지 애매했다.
    • 알림(notification) 테스트를 예로 들면:
      1. 처음부터 알림 시간에 맞춘 데이터를 넣고 곧바로 알림이 뜨는지만 확인하는 방법
      2. 시간을 흘려보내 알림이 발생하는 과정을 검증하는 방법
      3. 알림 생성부터 발생까지 모든 플로우를 따라가는 방법
        중복을 피하기 위해 2번을 선택했지만, 어떤 방식이 “정석”에 가까운지는 확신이 없다.

기술적 성장

  • 단순히 테스트 메서드의 사용법을 넘어, 테스트 설계 관점을 고민하게 된 게 가장 큰 성장이다.
  • “UI를 찾는 방법, 이벤트를 발생시키는 방법, 검증하는 방법”을 조합해서 실제 유저 시나리오를 어떻게 시뮬레이션할지 고민하면서, 단순 코드 작성이 아닌 QA적 사고를 익힐 수 있었다.
  • 앞으로는 “무엇을 어디까지 검증해야 하는가?”라는 기준을 더 정교하게 세워야겠다고 느꼈다.

아쉬운 점 & 다음 목표

  • Mock 데이터와 Handler를 한눈에 파악하기 어렵다는 점은 여전히 아쉬웠다. 데이터와 로직을 분리한 게 장점이지만, 수정·삭제 시 다시 함수를 찾아가야 한다는 단점도 명확했다.
  • 다음부터는 목 데이터와 목 함수의 역할을 분리하거나, 테스트용 데이터셋을 별도 파일로 관리하는 구조를 시도해보고 싶다.