8주차 과제 체크포인트
기본 과제
필수
- 반복 유형 선택
- 일정 생성 또는 수정 시 반복 유형을 선택할 수 있다.
- 반복 유형은 다음과 같다: 매일, 매주, 매월, 매년
- 31일에 매월을 선택한다면 -> 매월 마지막이 아닌, 31일에만 생성하세요.
- 윤년 29일에 매년을 선택한다면 -> 29일에만 생성하세요!
- 반복 일정 표시
- 캘린더 뷰에서 반복 일정을 시각적으로 구분하여 표시한다.
- 아이콘을 넣든 태그를 넣든 자유롭게 해보세요!
- 캘린더 뷰에서 반복 일정을 시각적으로 구분하여 표시한다.
- 반복 종료
- 반복 종료 조건을 지정할 수 있다.
- 옵션: 특정 날짜까지, 특정 횟수만큼, 또는 종료 없음 (예제 특성상, 2025-06-30까지)
- 반복 일정 단일 수정
- 반복일정을 수정하면 단일 일정으로 변경됩니다.
- 반복일정 아이콘도 사라집니다.
- 반복 일정 단일 삭제
- 반복일정을 삭제하면 해당 일정만 삭제합니다.
선택
- 반복 간격 설정
- 각 반복 유형에 대해 간격을 설정할 수 있다.
- 예: 2일마다, 3주마다, 2개월마다 등
- 예외 날짜 처리:
- 반복 일정 중 특정 날짜를 제외할 수 있다.
- 반복 일정 중 특정 날짜의 일정을 수정할 수 있다.
- 요일 지정 (주간 반복의 경우):
- 주간 반복 시 특정 요일을 선택할 수 있다.
- 월간 반복 옵션:
- 매월 특정 날짜에 반복되도록 설정할 수 있다.
- 매월 특정 순서의 요일에 반복되도록 설정할 수 있다.
- 반복 일정 전체 수정 및 삭제
- 반복 일정의 모든 일정을 수정할 수 있다.
- 반복 일정의 모든 일정을 삭제할 수 있다.
심화 과제
- 이 앱에 적합한 테스트 전략을 만들었나요?
각 팀원들의 테스트 전략은?
본격적으로 토의를 시작하기 전에 각자가 생각하는 최적의 전략을 적어 소개하고자 하였습니다.
이지훈
- 전략: 테스트 트로피 전략
- 핵심 관점: 사용자 관점에서의 정상 동작 확인이 핵심
- 접근법:
- 통합 테스트 중심으로 사용자 시나리오 검증
- 훅과 같이 데이터와 상태를 다루는 로직은 단위 테스트로 보완
이은지
- 전략: 테스트 트로피 전략 + Outside-in TDD
- 핵심 관점: 오버엔지니어링 방지와 큰 그림부터 접근
- 접근법:
- E2E 테스트 → 통합 테스트 → 단위 테스트 → 구현 순서
- 사용자 시나리오 위주의 통합테스트부터 시작해 점진적으로 구현 범위 축소
- 비율: 단위 20-30%, 통합 50-60%, E2E 5-15%
- 특징: 중요한 단위 로직들은 통합 테스트를 통해 간접 검증 가능
허정석
- 전략: 다이아몬드 형 (단위 테스트 중심)
- 핵심 관점: 빠른 피드백과 비용 효율성 중시
- 접근법:
- 단위 테스트로 빠른 버그 감지 (UI 컴포넌트, 유틸 함수, 상태 관리)
- 통합 테스트로 실제 환경과 유사한 검증 (MSW 활용)
- E2E는 핵심 유저 플로우만 선별적 적용
- 비율: 단위 60-70%, 통합 20-30%, E2E 5-10%
주산들
- 전략: 단위 테스트 중심 + 트로피 (TDD 개발 방식 고려)
- 핵심 관점: TDD 개발에 적합한 점진적 접근
- 접근법:
- 작은 유닛 테스트부터 시작해 점진적으로 비용이 큰 테스트로 확장
- Green Zone 진입 후 통합 테스트로 검증
- 과제의 단일 기능 특성상 유닛 테스트 접근이 용이
- 순서: 유닛 → 통합 → E2E
윤영서
- 전략: 테스트 트로피 전략
- 핵심 관점: 비용 대비 신뢰도의 균형점 추구
- 접근법:
- 통합 테스트가 핵심: 실제 유저 플로우와 흡사하면서도 구현 변경에 영향 적음
- 단위 테스트: 저렴하지만 리팩토링 시 취약성 존재
- 리액트 컴포넌트 간 통합의 중요성 강조
- 참고 자료: Kent C. Dodds의 Testing Trophy 개념
여찬규
- 전략: 단위 테스트 중심의 피라미드 구조
- 핵심 관점: 개발 속도와 비용 효율성 우선
- 접근법:
- 빠르고 저렴한 단위 테스트 중심
- 느리고 비싼 E2E 테스트는 최소화
- 비율: 단위 70%, 통합 20%, E2E 10%
합의된 테스트 전략과 그 이유는 무엇인가요?
최종 결정: 테스트 트로피 전략
선택 이유
- 실용적 균형점: 비용 대비 효과를 고려했을 때 통합 테스트가 가장 실용적
- 사용자 관점의 테스트를 통해 실제 동작 확인 가능
- 구현 세부사항 변경에 상대적으로 덜 민감
- 리액트 생태계 특성: 컴포넌트 간 상호작용과 통합이 중요한 프론트엔드 특성 고려
- 개별 컴포넌트보다는 화면 단위의 사용자 시나리오가 더 중요
- React Testing Library 등을 활용한 통합 테스트가 효과적
- 오버엔지니어링 방지: 과도한 단위 테스트로 인한 비효율성 방지
- 구현이 확정되지 않은 초기 단계에서 과도한 단위 테스트는 비효율적
- 통합 테스트를 통해 여러 단위 로직을 간접적으로 검증 가능
- 유지보수성: 리팩토링과 구현 변경에 대한 안정성 확보
- 인터페이스가 동일하면 내부 구현 변경에 영향을 받지 않음
- 하나의 테스트로 여러 기능을 동시에 검증 가능
적용 방향
- 통합 테스트 중심: 사용자 시나리오와 주요 플로우 검증에 집중
- 선별적 단위 테스트: 복잡한 비즈니스 로직, 유틸 함수, 훅 등 핵심 로직만 선별
- 최소한의 E2E: 가장 중요한 사용자 여정만 선별하여 적용
이러한 전략을 통해 개발 효율성과 테스트 신뢰성의 최적 균형점을 찾고자 합니다.
추가로 작성된 테스트 코드는 어떤 것들이 있나요?
-
단위 테스트 반복되는 이벤트를 생성하기 위한 유틸 함수(createRepeatEvents)를 만들었고, 이를 테스트 하기 위해
easy.eventUtils.spec.ts파일 내부에 단위 테스트 로직을 작성하였습니다. -
통합 테스트 기존 통합 테스트 로직이 존재하는
medium.integration.spec.tsx파일 내부에 작성하였습니다. 이번에 합의한 전략에 의거하여 가장 큰 비중을 가지고 있습니다. -
E2E 테스트 playwright 환경을 세팅하여 통합테스트와 같은 레벨인
events.e2e.ts파일 내부에 작성하였습니다. 대략적이고 전반적인 시나리오에 대해 테스트를 진행합니다.
과제 셀프회고
드디어 해봤다 TDD!!!!
처음에는 TDD를 어떻게 해야할지도 몰라서 뭔가.. 상당한 내공과 통찰이 필요한 개발 방법론이라는 생각을 하고 있었다.
나는 TDD가 개발 과정을 머릿속에 촤촤촥 그려놓고 나서 테스트를 그에 맞게 미리 작성해 둔 다음에 코드를 테스트에 맞게 작성하는 방법론이라고 생각했다. (과거의 내가 대체 왜 이렇게 생각하고 있었는지는 모르겠지만 어렴풋이 이 모든것을 한방에 해야한다고 여겼음... 그래서 과제 처음 받고 와 엄청 어렵겠다고 생각함)
아니.. 주변에서 막 TDD는 내공이 있어야 가능하다 그래서.........🫣
근데
- 목표를 설정하고
- 실패할 과정(실패할 테스트)을 그린 다음에
- 목표에 맞는 코드를 작성하고
- 테스트 코드를 수정하는 방식
이렇게 진행을 하는게 TDD라고 해서 지금까지 내가 잘못 생각해왔음을 알 수 있었고(다행이다) 이번에 TDD를 경험하게 되어서 좋았다. 나는 개발하면서 쓸데없는 생각을 많이 해서 종종 개발 중간에 길을 잃어버려가지고 멍을 때리는데 TDD를 하게 되니까 목표가 뚜렷해져서 좋았다.
그리고 팀원들과 심화과제를 수행하기 위한 토론을 할 때 나는 처음에 테스트 트로피 전략이 아닌 피라미드 전략을 하자고 주장했다. 왜냐하면 이번에 TDD로 개발을 진행할 예정이니까 작은 유닛 테스트를 많이 작성해두고 개발을 진행한 다음에 어느정도 Green Zone에 들어가고 나서 통테를 작성하여 검증을 하는 게 효율적이고 편할 것 같다고 생각했기 때문이다.
그리고 영서님께 핵심을 찌르는 질문을 받고 할 말이 없어졌다.
"이번 과제에서 주어진 요구사항을 보고 따로 생각나는 (추가할만한) 유닛 테스트들이 있으신가요?" "생각하시는 유닛 테스트들의 양이 많으신가요?" (워딩이 정확하지는 않습니다.. 기억나는대로 적었습니다..)
딱 질문을 듣고 생각해봤는데 크게 더 생각이 나지 않았다... 오히려 로직을 검증하는데 필수적으로 필요한거 정도만 "이런건 있어야겠다" 정도로 생각이 났고 더 추가할 것... 은 딱히 생각이 나지 않았다. 뭔가 더 추가된다면 그것은 불필요한 테스트 일 것 같았다.
그래서 다시 생각해봤다. 그런데 TDD를 하려면 테스트를 적으면서 해야되지 않나? 그러려면 테스트 규모가 작아야 하는거 아닌가? 생각이 들어서 팀원들에게 질문했었는데 내가 뭔가 TDD에 대한 착각을 하고 있었음을 깨달았다. 그리고 지금 상황에서 가장 효용성이 있을법한 테스트는 통합테스트라는 생각이 들었다. 유닛테스트는 통합 테스트의 안정성을 보좌하는 역할이 될 것 같았고... E2E는 중요한 전반적인 로직을 쭉 둘러보는 용도로 하지만 메인은 아닌 정도로 쓰면 되겠다 생각이 들었고 아 그래서 팀원들이 트로피 전략을 이야기하신거였구나.. 하고 이해가 되었다. 그리고 이후에 나는 순간적으로 효용성 있는 테스트가 아니라 내가 작성하기 편한 테스트를 작성하려고 계획했던 것은 아닌가 반성이 되었다.
기술적 성장
이번에는 처음으로 playwright 테스트(E2E 테스트)를 작성해 봤는데, E2E 테스트를 작성해보면서 이제는 테스트 코드가 좀 만만해졌음(?)을 느꼈다. RTL이랑 문법이랑 작동하는 방식이 비슷해서 그럴수도 있겠다... RTL은 이제 약간 어림잡아서 이렇게이렇게 하면 내가 생각한대로 테스트가 될거같은데? 하고 코드를 작성하면 코드가 쇽쇽 통과되는 것 같다. 뭔가 감이 생겨서 코드를 생각하고 적는 속도가 빨라진 듯 하다.
코드 품질
아직은 좀 찍어내는 테스트 코드 느낌이 나는 것 같기도 한데 그래도 뭔가 익숙해지고 있는 것 같다. 점점 더 익숙해 질 수록 다양한 문법과 메서드를 숙지하고 사용할 수 있지 않을까 생각중이다.
학습 효과 분석
이번 챕터들을 진행하면서 해야지 해야지 해봤던 테스트 코드를 직접 작성해봤다는거! 그리고 TDD 방식으로 개발을 해봤다는거! 그 자체가 의미가 크고 내면의 진입장벽을 많이 없애주는 계기가 되었던 것 같다. 테스트 코드 문법에 익숙해진 것은 덤이고.. 실무 적용은 얼른 해보고 싶다!!! 멘토링 때 은지님께서는 벌써 현재 회사에서 하는 프로젝트에 테스트 코드를 적용해보려고 하시던데 너무 멋있게 느껴졌고 부러웠다!!! 나도 전 회사 프로젝트에서 테스트 코드가 도입되면 좋았을 프로젝트들이 생각이 났고(그래서 아쉬웠다 ㅠㅠ) 새로 시작할 내 개인 프로젝트에도 적용해봐야지 생각이 들어서 설렜다.
과제 피드백
TDD라고 해서 처음에는 조금 겁을 먹었는데(제가 이상한 오해를 하고 있었어서...) 생각보다 수월하게 잘 진행한 것 같습니다!! 난이도는 괜찮았고 이번 주차는 저번 주에 비해서는 약간 쉬운 편이었던 것 같아요!
리뷰 받고 싶은 내용
- E2E 테스트는 API를 모킹하지 않고 진행을 하잖아요, 근데 그러면 예를 들어서 뭔가를 추가하는 테스트 코드를 구현을 하고 그것을 실행했을 때 그게 실제로 추가가 되는건데 그럼 테스트를 진행하며 쓸데없는 데이터들이 잔뜩 생기는 것을 방지하기 위해 보통 삭제 로직도 같이 만들어서 실행을 해 주나요? 뭔가를 생성하는 테스트는 테스트를 한번 돌릴 때마다 데이터들이 생겨날텐데 E2E 테스트를 할 때 이걸 신경써야 하나요? 만약 신경을 써줘야 한다면 이런걸 관리하는 전략이나 방법이 있나요?
과제 피드백
수고했습니다. 이번 과제는 테스트를 하는 다양한 방법들을 접하면서 테스트 코드를 작성한다라는 그 심리적 장벽을 허물고 친숙해지는데 있었습니다. 회고를 보아하니 잘 수행해준 것 같아요.
"과제를 처음 시작할 때 테스트 코드 자체를 아예 처음 해보는 거라 내가 과제를 잘 수행 할 수 있을지 걱정이 많이 되었다. 그런데 막상 해보니까 생각보다 문법이 간단했고 아 뭐야! 괜히 쫄았네!!" ㅋㅋ 좋은 반응이네요. 실제로 테스트 코드는 생각보다 진입장벽이 높지 않아요. 한번 해보면 "아 이런 거구나" 싶죠.
"밀린 숙제 끝낸 느낌이고... 일단은 앞으로 개발하면서 '테스트 코드를 도입해 볼까?' 라는 생각이 쉽게 들 것 같아서 좋다. 심리적 진입장벽이 많이 낮아졌다..." 너무 좋습니다. 무엇보다 심리적 진입장벽이 많이 낮아졌다는 말이 참 좋네요. 이게 이번 과제의 가장 큰 목표였어요. 테스트 코드에 대한 막연한 두려움을 없애는 것!! 이제는 마지막 퍼즐조각인 실무에서도 어떻게든 하나 만들어 보는 것 까지 자연스럽게 시도해볼 수 있을 거예요.
"나중에는 테스트 코드가 없이 리팩토링을 할 때 불편함을 느낄 수도 있을 것 같았다" 정확한 인사이트네요. 테스트 코드가 있는 상태에서 리팩토링을 경험해보면, 없을 때의 불안감을 더 크게 느끼게 되죠.
"최대한 공정한...? 코드를 작성하려고 노력했다. 막 어떻게든 테스트를 통과시키기 위해 기상천외한 방식으로 테스트를 작성하는 것은 최대한 지양하고자 하였고...." 좋습니다. 공정한이라는 표현이 재밌네요. 테스트 코드는 나를 대신해서 사용자를 대신해서 하는 것인만큼
Q) 테스트 코드는 다다익선인가요! 테스트 코드가 많을 경우 생길 수 있는 단점이 있나요?
=> 좋은 질문입니다. 당연히 코드는 많을 수록 좋겠죠? 가 아니라 테스트 코드도 결국 코드이기 때문에 유지보수 비용이 발생했습니다. 코드는 자산이 아니라 부채니까요. 우리가 담보 대출을 받아 집을 사고 이자를 내는 건 그 편이 더 큰 가치를 만들어 내기 때문이죠. 그러나 실제 가치를 얻기도 전에 이자에 허덕인다면 좋을 수 없습니다. 주담대도 땡길 수 있을때 많이 땡기는게 좋지만 감당할 수 있느냐가 중요하다고 생각해요.
=> 테스트 코드는 그 특성상 요구사항이 변경되면 그에 맞게 테스트 코드를 수정해야 되요. 테스트 코드가 아주 세세하게 많다면 그 변화에 맞게 코드 수정까지 해야 되죠. 그리고 테스트 실행시간이 길다면 매번 코드 변경시 테스트 코드를 실행하게 되고 이게 늘어진다면 되려 속도가 느려질 수 있습니다. 그리고 테스트 코드는 꽤나 중요한 기준이 되어 주는데 테스트 코드가 틀리게 될 경우 검증을 하는게 어려워질 수 있습니다.
=> 사실 이런걸 재다보면서 테스트 코드를 만들면 결국 하지 말자는 식의 결론이 내려질 가능성이 크기 때문에 일단 만들어보고 판단해도 늦지 않아요. 만들다보면 필요없는 테스트, 필요한 테스트들이 보이게 됩니다. 물론 그 규모가 커지게 되고 관리하던 누군가가 손을 떼는 순간 그 부작용을 경험하게 되겠지만 그건 그때가서 생각해보기로 하고 일단 만들어 보기로 해요! 거기까지 도착해보는 것만으로도 크게 성장할테니까요
이번 경험으로 테스트에 대한 두려움이 사라진 만큼, 실무에서도 꼭 한번씩 시도해보면서 그 가치를 계속 확인해보길 바라요. 다음 과제도 화이팅입니다