테스트 코드는 항상 중요하다고 생각했지만, 실제로 적용하기에는 무겁게 느껴졌습니다. 하지만 이번 프로젝트에서 처음으로 본격적인 테스트 코드를 작성해보며 많은 것을 배우고 성장할 수 있었습니다.
처음에는 막막했습니다. 무엇부터 테스트해야 할지, 어떻게 접근해야 할지 감이 잡히지 않았습니다. 그래서 다음과 같은 단계적 접근법을 취했습니다:
// 처음에는 이렇게 작성했으나 테스트가 불안정했습니다
fireEvent.click(screen.getByText('응시기간 설정'));
expect(screen.getByText('응시 기간 설정')).toBeInTheDocument();
// waitFor를 사용해 안정적인 테스트로 개선
fireEvent.click(screen.getByText('응시기간 설정'));
await waitFor(() => {
expect(screen.getByText('응시 기간 설정')).toBeInTheDocument();
});
테스트를 작성하다 보니 불필요한 리렌더링이 발생하는 부분을 발견했습니다.
// 최적화 전const dateInputClasses = `${styles.dateInput} ${isCalendarOpen ? styles.active : ''}`;
// 최적화 후const dateInputClasses = useMemo(
() => `${styles.dateInput} ${isCalendarOpen ? styles.active : ''}`,
[isCalendarOpen]
);
셀렉터도 메모이제이션이 필요했습니다:
// 최적화 전export const selectExamPeriod = (state: RootState) => ({
startDate: state.examPeriod.startDate,
endDate: state.examPeriod.endDate,
});
// 최적화 후 (메모이제이션 적용)export const selectExamPeriod = createSelector(
(state: RootState) => state.examPeriod.startDate,
(state: RootState) => state.examPeriod.endDate,
(startDate, endDate) => ({ startDate, endDate })
);
테스트 코드에서는 주석이 더욱 중요하다는 것을 깨달았습니다. 특히 특정 상태를 설정하거나 검증하는 단계에서 주석이 있으면 코드의 의도를 명확히 파악할 수 있습니다.
// API 성공 응답 설정
(projectsAPI.fetchProjects as jest.Mock).mockResolvedValue(mockProjects);
// Saga 실행await runSaga(...)
// 디스패치된 액션 검증expect(dispatched[0].type).toBe(fetchProjectsSuccess.type);