8주차 과제 체크포인트
기본 과제
필수
- 반복 유형 선택
- 일정 생성 또는 수정 시 반복 유형을 선택할 수 있다.
- 반복 유형은 다음과 같다: 매일, 매주, 매월, 매년
- 31일에 매월을 선택한다면 -> 매월 마지막이 아닌, 31일에만 생성하세요.
- 윤년 29일에 매년을 선택한다면 -> 29일에만 생성하세요!
- 반복 일정 표시
- 캘린더 뷰에서 반복 일정을 시각적으로 구분하여 표시한다.
- 아이콘을 넣든 태그를 넣든 자유롭게 해보세요!
- 캘린더 뷰에서 반복 일정을 시각적으로 구분하여 표시한다.
- 반복 종료
- 반복 종료 조건을 지정할 수 있다.
- 옵션: 특정 날짜까지, 특정 횟수만큼, 또는 종료 없음 (예제 특성상, 2025-06-30까지)
- 반복 일정 단일 수정
- 반복일정을 수정하면 단일 일정으로 변경됩니다.
- 반복일정 아이콘도 사라집니다.
- 반복 일정 단일 삭제
- 반복일정을 삭제하면 해당 일정만 삭제합니다.
선택
- 반복 간격 설정
- 각 반복 유형에 대해 간격을 설정할 수 있다.
- 예: 2일마다, 3주마다, 2개월마다 등
- 예외 날짜 처리:
- 반복 일정 중 특정 날짜를 제외할 수 있다.
- 반복 일정 중 특정 날짜의 일정을 수정할 수 있다.
- 요일 지정 (주간 반복의 경우):
- 주간 반복 시 특정 요일을 선택할 수 있다.
- 월간 반복 옵션:
- 매월 특정 날짜에 반복되도록 설정할 수 있다.
- 매월 특정 순서의 요일에 반복되도록 설정할 수 있다.
- 반복 일정 전체 수정 및 삭제
- 반복 일정의 모든 일정을 수정할 수 있다.
- 반복 일정의 모든 일정을 삭제할 수 있다.
심화 과제
- 이 앱에 적합한 테스트 전략을 만들었나요?
과제를 시작함에 있어 심화과제에 대한 테스트전략을 합의하기 위해 코어타임에 각자 어떤 테스트 전략을 사용하면 좋을지 논의했습니다. 주로 트로피 전략파와 피마리드 전략파로 나뉘었고, 결론적으로 트로피 전략을 사용하기로 정했습니다.
각 팀원들의 테스트 전략은?
🏆 테스트 트로피 전략 지지자들
- 이지훈: 사용자 관점에서의 정상 동작 확인이 핵심이라고 판단. 통합 테스트 중심으로 사용자 시나리오 검증하고, 훅과 같이 데이터와 상태를 다루는 로직은 단위 테스트로 보완
- 이은지: Outside-in TDD 방식 채택 (E2E → 통합 → 단위 → 구현). 오버엔지니어링 방지를 위해 사용자 시나리오부터 시작해 점진적으로 구현 범위 축소. 비율 제안: 단위 20-30%, 통합 50-60%, E2E 5-15%
- 윤영서: Kent C. Dodds의 Testing Trophy 개념 참고. 리액트 컴포넌트 간 통합의 중요성 강조하며, 통합 테스트가 실제 유저 플로우와 흡사하면서도 구현 변경에 영향을 적게 받는다고 판단
🔺 테스트 피라미드 전략 지지자들
- 허정석: 다이아몬드 형 구조 제안. 빠른 피드백과 비용 효율성을 중시하여 단위 테스트 중심(60-70%), 통합 테스트(20-30%), E2E(5-10%)로 구성
- 주산들: TDD 개발 방식을 고려한 점진적 접근. 작은 유닛 테스트부터 시작해 Green Zone 진입 후 통합 테스트로 검증하는 방식 선호
- 여찬규: 개발 속도와 비용 효율성 우선. 단위 70%, 통합 20%, E2E 10% 비율 제안
합의된 테스트 전략과 그 이유는 무엇인가요?
최종적으로 합의된 테스트 전략은 트로피 전략입니다. 트로피 전략을 선택하게된 가장 큰 이유는 실용적인 관점에서 통합 테스트의 비중을 높이는 것이 사용자 시나리오 위주의 실제 환경과 비슷한 테스트를 수행하기 때문입니다. 그리고 리액트 생태계 특성상 모듈 개별 단위보다 여러 모듈이 통합됐을때 상호작용과 예상치 못한 버그 등이 있을 수 있기 때문에 컴포넌트간 상호작용과 통합에 대한 시나리오가 더 중요하다고 생각했습니다.
추가로 작성된 테스트 코드는 어떤 것들이 있나요?
최소한의 e2e 테스트를 추가적으로 작성하고, 기본적으로 주어진 유닛 테스트 시나리오에서 커버하지 못하고 있는 테스트 케이스들을 추가했습니다.
추가로 작성된 테스트 코드
기본 요구사항 외 추가 테스트 코드 (총 12개 파일)
- 단위 테스트 (7개 파일)
🔄 반복 일정 관련
repeatLogic.spec.ts (187줄) generateRepeatEvent 함수의 다양한 반복 유형별 테스트
- 매일/매주/매월/매년 반복 로직 검증
- 경계값 테스트 (31일, 윤년 등)
- 종료 날짜 처리 로직
📋 이벤트 관리 관련
easy.eventUtils.spec.ts (400줄) getFilteredEvents 함수 테스트
- 검색 기능 (제목, 설명, 위치)
- 날짜 범위별 필터링 (주간/월간)
- 반복 일정 관련 유틸리티 함수
- 통합 테스트
medium.integration.spec.tsx
🔄 반복 일정 생성 테스트
- 매일 반복: 위클리뷰/이벤트 목록에 표시 확인
- 매일 반복: 먼슬리뷰에 오늘 이후로 매일 표시
- 반복 아이콘: 반복 일정에 아이콘 표시, 일반 일정에는 없음
- 매주 반복: 위클리뷰/이벤트 목록에 표시
- 매주 반복: 먼슬리뷰에 오늘 이후로 매주 표시
- 매월 반복: 위클리뷰/이벤트 목록에 해당 일정만 표시
- 매월 반복: 먼슬리뷰에 해당 일정만 표시
- 매년 반복: 위클리뷰/이벤트 목록에 해당 일정만 표시
- 매년 반복: 먼슬리뷰에 해당 일정만 표시
🔢 매월 반복 일정 경계값 테스트
- 31일 매월 반복: 31일이 있는 달(1,3,5,7,8월)에만 일정 생성
- 윤년 2월 29일: 평년 2월에는 일정 생성되지 않음
⏰ 반복 종료일 테스트
- 사용자 설정 종료일: 2025-10-15까지만 반복 일정 생성
- 최대 종료일 초과: 2025-10-30까지만 반복 일정 생성
- 종료일 미설정: 최대 종료일(2025-10-30)까지만 반복 일정 생성
✏️ 반복 일정 수정 테스트
- 매일 반복 수정: 단일 일정으로 변경되어 반복 아이콘 사라짐
- 매주 반복 수정: 해당 일정만 단일 일정으로 변경
- 매월 반복 수정: 해당 일정만 단일 일정으로 변경
🗑️ 반복 일정 삭제 테스트
- 매일 반복 삭제: 해당 일정만 삭제되고 나머지는 유지
- E2E 테스트
🎯 사용자 시나리오
repeatEndDate.e2e.spec.ts (145줄)
- 반복 종료일 설정 시나리오
- 실제 브라우저에서의 사용자 플로우 검증
- UI 컴포넌트 상호작용 테스트
과제 셀프회고
기술적 성장
TDD를 처음 경험하면서 기존의 개발 방식과는 완전히 반대되는 접근법에 적응하는 것이 가장 큰 어려움이었습니다. 구현된 코드가 전혀 없는 상태에서 테스트 시나리오를 작성하고, 의도적으로 실패하는 테스트를 먼저 작성한 후 점진적으로 코드를 발전시켜나가는 Red-Green-Refactor 사이클이 처음에는 매우 어색했습니다. 특히 초반에는 "무엇을 테스트해야 할지"부터 막막해서 과제 진행 속도가 현저히 느려졌습니다.
하지만 TDD 프로세스에 익숙해지면서 예상치 못한 개인적 성장을 경험했습니다. 평소 "일단 코드부터 작성하고 문제가 생기면 해결하자"는 접근 방식을 선호했던 저에게, TDD는 구현 전에 충분히 고민하도록 강제하는 유익한 제약이 되었습니다.
학습 효과 분석
- 요구사항 분석 능력 향상: 테스트를 먼저 작성하려면 기능의 입력, 출력, 예외 상황을 명확히 정의해야 했습니다
- 엣지 케이스 사전 발견: 윤년 29일의 매년 반복, 31일의 매월 반복 등 복잡한 비즈니스 로직의 경계 조건들을 구현 전에 미리 식별할 수 있었습니다
- 설계 품질 개선: 테스트하기 쉬운 코드를 작성하다 보니 자연스럽게 함수의 책임이 분리되고 의존성이 낮아졌습니다
- 개발 신뢰도 증가: 각 단계마다 테스트가 통과하는 것을 확인하면서 진행하니 리팩토링이나 기능 확장 시에도 안정감을 느낄 수 있었습니다
무엇보다 "머릿속으로 개발 사이클을 미리 돌려보는 능력"이 크게 향상된 것을 체감했습니다. 이는 앞으로의 개발 업무에서도 큰 도움이 될 것 같습니다.
리뷰 받고 싶은 내용
테스트 코드의 유지보수성과 가독성 사이의 균형점에 대한 조언
현재 반복 일정 관련 테스트 코드를 작성하면서 중복되는 코드가 많이 발생하고 있습니다. 예를 들어, 반복 일정 생성 시나리오, 수정 시나리오, 삭제 시나리오에서 공통적으로 사용되는 테스트 데이터 준비나 DOM 조작 코드들이 반복되고 있습니다.
고민사항:
-
공통화 vs 가독성의 딜레마: 일반 코드처럼 공통 함수로 추출하면 중복은 줄일 수 있지만, 테스트 시나리오를 파악할 때 여러 파일을 오가며 읽어야 해서 오히려 이해하기 어려워질 것 같습니다. 테스트 코드에서는 어느 정도의 중복을 허용해야 하는지 기준이 궁금합니다.
-
테스트 유틸리티 함수의 적정 범위: 현재 헬퍼 함수들을 만들었는데, 이런 함수들을 어느 수준까지 추상화해야 테스트의 의도는 명확히 유지하면서도 유지보수성을 확보할 수 있을까요?
-
UI/UX 변경에 따른 테스트 취약성: 현재 React Testing Library를 사용해서 getByText, getByRole 등으로 요소를 찾고 있는데, UI 문구나 구조가 변경될 때마다 테스트가 깨지는 상황이 자주 발생합니다. 이런 변경에 더 유연하게 대처할 수 있는 테스트 작성 방법이 있을까요?
과제 피드백
수고했습니다. 이번 과제는 TDD 방법론을 실제로 경험해보면서 테스트 주도 개발의 Red-Green-Refactor 사이클을 체험하는데 목적이 있었습니다. 팀 전체가 테스트 전략 논의부터 시작해서 체계적으로 접근한 점이 인상적이었어요.
"구현된 코드가 전혀 없는 상태에서 테스트 시나리오를 작성하고, 의도적으로 실패하는 테스트를 먼저 작성한 후 점진적으로 코드를 발전시켜나가는 Red-Green-Refactor 사이클이 처음에는 매우 어색했습니다." 정말 솔직한 고백이네요. TDD를 처음 접하는 모든 개발자가 겪는 과정이에요. 기존 개발 방식과 정반대니까요.
"Outside-in TDD 방식 채택 (E2E → 통합 → 단위 → 구현)" 이런 접근 방식을 의식적으로 선택하고 적용한 점이 좋았습니다. 오버엔지니어링을 방지하면서 사용자 관점에서 시작하는 이 방식은 실무에서도 매우 유용해요.
"머릿속으로 개발 사이클을 미리 돌려보는 능력이 크게 향상된 것을 체감했습니다." 이게 바로 TDD의 핵심 가치 중 하나예요. 코딩하기 전에 충분히 생각하게 만드는 강제성이 결국 더 나은 설계로 이어지죠.
작성하신 테스트 코드 목록을 보니 정말 체계적으로 접근하셨네요. 특히 경계값 테스트(31일, 윤년)나 반복 종료일 처리 등 복잡한 비즈니스 로직의 엣지 케이스까지 꼼꼼히 다루신 점이 훌륭합니다.
Q) 공통화 vs 가독성의 딜레마:
=> 테스트 코드에서는 일반 코드보다 중복을 더 허용하는 편이 좋습니다. 테스트 코드의 목적은 "각 테스트가 무엇을 검증하는지 명확히 알 수 있는 것"이거든요. 그렇기에 반복과 관계없이 실제 명세에 가깝도록 작성하는게 좋습니다. 단, 실제로 추상화해서 말하고 있는 그대로라면 숨겨도 좋습니다.
그리고 추상화를 하더라도 헬퍼 함수에는 충분히 기획서에 가까운 주석을 자세히 달아두면 나중에 유지보수할 때 도움이 됩니다. 예를 들어 // 매일 반복 일정을 생성하고 월별 뷰에서 3개 이상 표시되는지 검증한다. 이런 식으로요.
Q) 테스트 유틸리티 함수의 적정 범위:
=> 공통화의 기준은 이렇게 잡아보세요: 1) 테스트 데이터 설정은 공통화해도 좋아요 (createTestEvent, setupMockData 같은), 2) 반복되는 DOM 조작도 헬퍼로 만들어도 좋지만 반복을 줄이기 위함보다는 테스트 의도가 드러나는 ex) 장바구니에 여러개 담기 형태로 작성해주세요. 3) 그리고 중요한건 추상화를 하더라도 검증 로직은 테스트에 다 드러나도록 작성해야 합니다. 테스트 항목이 추상화 안으로 숨겨지는건 좋지 않습니다.
Q) UI/UX 변경에 따른 테스트 취약성:
=> UI 변경에 유연한 테스트를 위해서는: 1) data-testid 활용을 늘리거나 role 기반이 유용합니다. 2) 너무 구체적인 선택자를 피하거나 (getByText('정확한 텍스트') 대신 getByText(/부분 텍스트/) 사용), 3) 혹은 i18n처럼 텍스트 선택자 역시 StringId를 통해서 가져오는 방식도 좋습니다.
앞으로 실무에서도 이런 체계적 접근을 활용하시면 코드 품질과 안정성을 크게 높일 수 있을 거예요. 다음 과제도 화이팅입니다! 수고하셔습니다.