bebusl 님의 상세페이지[2팀 이진희] Chapter 3-2. 프론트엔드 테스트 코드

8주차 과제 체크포인트

기본 과제

필수

  • 반복 유형 선택
    • 일정 생성 또는 수정 시 반복 유형을 선택할 수 있다.
    • 반복 유형은 다음과 같다: 매일, 매주, 매월, 매년
      • 31일에 매월을 선택한다면 -> 매월 마지막이 아닌, 31일에만 생성하세요.
      • 윤년 29일에 매년을 선택한다면 -> 29일에만 생성하세요!
  • 반복 일정 표시
    • 캘린더 뷰에서 반복 일정을 시각적으로 구분하여 표시한다.
      • 아이콘을 넣든 태그를 넣든 자유롭게 해보세요!
  • 반복 종료
    • 반복 종료 조건을 지정할 수 있다.
    • 옵션: 특정 날짜까지, 특정 횟수만큼, 또는 종료 없음 (예제 특성상, 2025-06-30까지)
  • 반복 일정 단일 수정
    • 반복일정을 수정하면 단일 일정으로 변경됩니다.
    • 반복일정 아이콘도 사라집니다.
  • 반복 일정 단일 삭제
    • 반복일정을 삭제하면 해당 일정만 삭제합니다.

선택

  • 반복 간격 설정
    • 각 반복 유형에 대해 간격을 설정할 수 있다.
    • 예: 2일마다, 3주마다, 2개월마다 등
  • 예외 날짜 처리:
    • 반복 일정 중 특정 날짜를 제외할 수 있다.
    • 반복 일정 중 특정 날짜의 일정을 수정할 수 있다.
  • 요일 지정 (주간 반복의 경우):
    • 주간 반복 시 특정 요일을 선택할 수 있다.
  • 월간 반복 옵션:
    • 매월 특정 날짜에 반복되도록 설정할 수 있다.
    • 매월 특정 순서의 요일에 반복되도록 설정할 수 있다.
  • 반복 일정 전체 수정 및 삭제
    • 반복 일정의 모든 일정을 수정할 수 있다.
    • 반복 일정의 모든 일정을 삭제할 수 있다.

심화 과제

  • 이 앱에 적합한 테스트 전략을 만들었나요? 팀원들과 전략은 세웠는데, 일정 관리 미스로.. 심화과제 테스트 코드를 구현하진 못했습니다.

각 팀원들의 테스트 전략은?

image [페어 2팀 테스트 전략 피그잼](https://www.figma.com/board/GeKV3mp3GvDSIpB2VN8BQT/2-6%ED%8C%80-%EC%8B%AC%ED%99%94%EA%B3%BC%EC%A0%9C-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%A0%84%EB%9E%B5?node-id=0-1&p=f&t=bz5WjllZQ0oHt22M-0)

저희팀은 피그잼에서 각 테스트에 대한 생각을 나누고, 어떠한 전략을 가져가겠다는 얘기를 나누었습니다. 대부분은 통합테스트의 양을 좀 더 늘리는게 좋겠다!라는 의견이었습니다. (각 팀원들의 테스트 전략을 모두 적으면 너무 길어질 것 같아, 피그잼 링크로 대체하겠습니다.)

합의된 테스트 전략과 그 이유는 무엇인가요?

결론적으로 해당 프로젝트에서는 E2E테스트가 크게 의미가 있을 것 같지 않으므로 기존 통합테스트를 좀 더 보강하면 좋겠다. 그리고 E2E테스트는 가장 핵심적인 플로우에 대해 하나정도 추가하면 좋겠다고 의견이 모였습니다. (전략 이름을 얘기하진 않았으나, 팀원들의 의견을 종합해보면 '테스트 피라미드' 전략으로 합의가 되었다고 보고 있습니다.)

추가로 작성된 테스트 코드는 어떤 것들이 있나요?

통합테스트 보완

  1. 폼 상태 관리 통합 테스트: 폼의 상태 변화, 초기화, 검증 등이 올바르게 동작하는지 검증
  2. 알림 시스템 전체 워크플로우 테스트 : 사용자가 알림을 설정하고, 시간이 되면 알림을 받고, 알림을 제거하는 전체 과정이 정상 동작하는지 검증
  3. 뷰 전환 및 네비게이션 통합 테스트: 뷰 전환 및 네비게이션 통합 테스트

E2E

  1. 일정 조회/추가/수정/삭제의 코어 기능 시나리오 시나리오 기준 생각해 본다면 
일정 추가 > 수정 > 삭제 > 화면 전환 기능 > 검색 > 반복 일정 추가 ...

과제 셀프회고

TDD 접근 방식에 대한 성찰

이번 과제는 TDD를 적용하는 것이 목표였지만, 완전한 TDD를 구현했다고 보기는 어려웠습니다. 제가 진행한 방식:

반복 일정 생성/수정/삭제에 대한 전체 테스트 코드 스켈레톤 작성 각 기능별 통합 테스트 코드 작성 (Red) 테스트를 통과시키는 코드 구현 (Green)

아쉬웠던 점: 정석적인 TDD라면 '반복 일정 날짜 계산 함수'와 같은 더 작은 단위부터 시작해서 각각에 대해 Red-Green-Refactor 사이클을 반복했어야 했는데, 처음부터 큰 덩어리의 통합 테스트를 작성하다 보니 전통적인 TDD 방식과는 거리가 있었습니다. 그래도 얻은 것: 비록 완전한 TDD는 아니었지만, Green 단계 구현 전에 테스트 코드를 작은 단위로 세분화하여 보강했고, 실제 구현 단계에서는 생성/수정/삭제 기능을 나누어 단계별로 작업했습니다. 이런 점에서 TDD의 핵심 철학인 '테스트 우선, 점진적 개발'을 어느 정도 경험해볼 수 있었다고 생각합니다.

테스트 환경 설정의 중요성 실무에서 테스트 코드를 작성해볼 기회가 없었는데, 이번 과제를 통해 직접 경험할 수 있어 매우 유익했습니다. 특히 인상 깊었던 것은 타이머 관리 부분이었습니다. setupTests.js의 beforeEach, afterEach에서 이미 타이머를 관리하고 있었는데, 이를 놓치고 새로 만든 테스트 파일의 describe 내부에서 vi.useFakeTimers(), vi.useRealTimers()를 중복 호출해서 테스트가 실패했던 경험이 있습니다. 이 과정을 통해 테스트 환경 설정의 중요성을 깨달았고, 앞으로 실무에서도 타이머나 전역 상태와 같은 부분들을 더욱 주의 깊게 살펴보고 작성할 것 같습니다. 더불어 각각 테스트를 실행할 때는 잘 통과하다가, describe전체를 테스트하면 같은 테스트에서 실패하는 경험을 했는데 테스트 간의 격리와 초기화가 얼마나 중요한지 정말 몸소 느낄 수 있었습니다.ㅠㅠㅠ 테스트 코드를 작성할 땐 정말 클린업을 잘!!해주고 목 데이터같은 경우도 테스트 코드별로 독립적으로 작동하게끔 잘 작성할 수 있게 된 것 같습니다.

궁금한 점

1. Red 단계에서 테스트 코드 수정이 필요한 경우 처리 방법 Red 단계에서 테스트 코드를 작성할 때 한 번에 완벽한 테스트를 만들기가 쉽지 않더라구요. Green 단계에서 구현을 진행하다 보니 테스트 코드가 잘못되었다는 걸 깨닫게 되는 경우가 있었는데, 이때 Green 구현을 중단하고 Red 코드를 다시 수정해서 커밋한 후, 그에 맞춰 구현을 이어서 진행하고 Green 코드를 커밋하는 방식으로 처리해도 되는 건지 궁금합니다. 아니면 이런 상황 자체가 TDD를 잘못 접근한 것일까요?

2. TDD 진행 순서: Top-down vs Bottom-up 이번 과제에서는 큰 덩어리의 통합 테스트를 먼저 작성하고, 리팩토링 과정에서 더 작은 단위의 함수로 쪼개면서 각각에 대해 다시 TDD를 적용하는 방식으로 진행하는 게 좋다고 생각했습니다.

예를 들어:

// 1. 먼저 이런 큰 덩어리의 통합 테스트 작성
it('반복 일정을 생성하면 캘린더와 리스트에 모두 표시된다', () => {
  // 전체 플로우 테스트
});

// 2. 구현 과정에서 작은 함수들로 쪼개면서
// 3. 각 함수에 대한 유닛 테스트 추가 작성
it('getRepeatedDates는 weekly 반복시 올바른 날짜들을 반환한다', () => {
  // 유닛 테스트
});

하지만 또 아래 예시처럼 작은 단위부터 TDD를 적용해나가며 통합 테스트를 구축하는 게 더 맞는 방향이 아닌가하는 생각이 들기도 했습니다.

// 1. 먼저 작은 단위부터 시작
it('getRepeatedDates는 weekly 반복시 올바른 날짜들을 반환한다', () => {});

// 2. 유닛들을 조합해서 
it('saveEvent는 반복 일정 데이터를 올바르게 처리한다', () => {});

// 3. 마지막에 통합 테스트
it('반복 일정을 생성하면 캘린더와 리스트에 모두 표시된다', () => {});

실제 실무에서는 어떤 순서로 진행하는 것이 더 효과적인지, 그리고 코드 구조나 함수 설계를 미리 어느 정도까지 계획하고, 어떤 순서로 TDD를 진행하는 게 맞는 건지 궁금합니다.

과제 피드백

  1. Red 단계에서 테스트 코드 수정이 필요한 경우 처리 방법: Red 단계에서 테스트 코드를 작성할 때 한 번에 완벽한 테스트를 만들기가 쉽지 않더라구요. Green 단계에서 구현을 진행하다 보니 테스트 코드가 잘못되었다는 걸 깨닫게 되는 경우가 있었는데, 이때 Green 구현을 중단하고 Red 코드를 다시 수정해서 커밋한 후, 그에 맞춰 구현을 이어서 진행하고 Green 코드를 커밋하는 방식으로 처리해도 되는 건지 궁금합니다. 아니면 이런 상황 자체가 TDD를 잘못 접근한 것일까요?

처음부터 테스트를 잘 작성하긴 어렵다고 생각해요 ㅎㅎ 말씀해주신 것 처럼 테스트의 red를 깔끔하게 유지하고 싶다면 이전 커밋을 수정해서 관리하는 방법이 있을 것 같은데, 꼭 그런 과정이 필요한가!? 라는 생각입니다. 결국 TDD도 개발을 잘 하기 위한 수단일 뿐이고 이게 목적이 되어서는 안 된다고 생각해요!

  1. TDD 진행 순서: Top-down vs Bottom-up: 이번 과제에서는 큰 덩어리의 통합 테스트를 먼저 작성하고, 리팩토링 과정에서 더 작은 단위의 함수로 쪼개면서 각각에 대해 다시 TDD를 적용하는 방식으로 진행하는 게 좋다고 생각했습니다. 실제 실무에서는 어떤 순서로 진행하는 것이 더 효과적인지, 그리고 코드 구조나 함수 설계를 미리 어느 정도까지 계획하고, 어떤 순서로 TDD를 진행하는 게 맞는 건지 궁금합니다.

무엇이 더 효과적일까 생각을 해보자면... TopDown의 경우 큰 덩어리에 대한 테스트를 작성할 때는 변경 가능성이 높다고 생각해요. 대신 전체적인 흐름에 대해 테스트를 작성하면서 이해하기가 쉬운 효과가 있다고 생각합니다. 테스트 자체보단 "어플리케이션에 대한 이해도"가 높아지는거죠 ㅎㅎ BottomUp의 경우 작은 함수 하나에 대해 작성하다보니 테스트의 정확도가 높고 변경 가능성이 낮다고 생각해요. 더 효율적인거죠.

무엇이 더 좋다기보단 상황에 맞는 선택을 해야한다고 생각해요. 내가 어떤 프로젝트에 갑자기 투입되어야 하는 상황이라면 통합테스트부터 작성하는게 좋을 수 있고, 빠르게 테스트를 토대로 리팩토링을 하고 싶다면 단위테스트부터 작성하면 되지 않을까요!?

정답이 있다기보단 목적에 따라 다르다고 생각합니다!