프론트엔드 테스트 자동화 연재의 3편으로 실제 테스트 코드를 어떻게 쓰는지 다룬다. 유닛 테스트는 AAA 패턴으로, 통합 테스트는 스토리북의 Interaction tests로 쓰는 구성을 예제와 함께 보여준다. 사용자 행동과 서버를 각각 어떻게 흉내낼지도 함께 짚는다.
핵심 포인트- 프론트엔드는 구성요소를 연결하는 역할이라 복잡한 단독 로직이 드물고 대부분 통합 테스트가 된다.
- 우편번호 검증이나 도서산간 판정처럼 입출력이 명확한 순수 함수는 분리해 유닛 테스트를 쓴다.
- 클래스 존재 여부나 컴포넌트 상태 같은 구현 세부는 검증 대상이 아니며 위양성의 원인이 된다.
- 다만 하위 컴포넌트에는 상위가 제어 밖의 요소이므로 콜백 호출과 props 동작이 요구사항이 된다.
- 통합 테스트는 사용자 여정을 따라가므로 AAA 대신 행동과 확인이 반복되는 형태가 된다.
- 스토리북을 잘 만들어뒀다면 검증 로직 없이 켜지는지만 보는 스모크 테스트로도 전환할 수 있다.
상세 정리- 유닛 테스트의 자리: 프론트엔드에서 직접 쓰는 순수 로직은 컴포넌트에서 함수로 추출해 엄밀히 검사하기를 권한다.
- 통합 테스트의 자리: UI 컴포넌트는 브라우저 환경과 사용자 상호작용, 서버 API를 전제하므로 함수 단위 입출력으로는 다룰 수 없다.
- 테스트 이름: 제주도 주소를 넣으면 특정 플래그가 참이 된다처럼 요구사항을 문장으로 적는다.
- AAA 패턴: 입력을 준비하고, 함수를 실행하고, 결과를 확인하는 세 단계로 나눠 무엇을 검증하려는 테스트인지 드러낸다.
- mock 도구: jest의 fn으로 호출 여부와 전달 인자를 기록하고, mock과 spyOn으로 파일 시스템이나 localStorage 같은 객체의 구현을 대체한다.
- mock에 대한 견해: Mockist와 Classical 전략이 갈리는데 프론트엔드에서는 Mockist를 따르기 어렵다고 본다.
- 프레임워크 관점: 테스트 프레임워크는 유닛과 통합을 구분하지 않으며 그 구분은 사람의 편의를 위한 것이다.
- 스토리북 활용: 이미 컴포넌트를 격리하고 목을 붙여둔 상태이므로 별도 통합 테스트를 쓰기보다 Interaction tests를 쓰는 편이 낫다.
- 예제 구성: 주소를 입력하고 저장을 누르면 저장 API가 호출되고 onClose가 불린다는 스토리 이름을 붙이고, play 함수 안에서 입력과 클릭을 시뮬레이션한 뒤 spy로 호출을 확인한다.
- 이름 짓는 기준: 사용자의 행동이나 props처럼 컴포넌트의 동작을 결정짓는 요소를 문장으로 적는다.
- 진행 패턴: 주소를 입력하고 확인하고 저장을 누르고 API 호출을 확인하고 콜백을 확인하는 식으로 행동과 확인이 번갈아 온다.
- 스모크 테스트: 별도 검증 없이 켜지는지만 보는 테스트이며, 스토리북이 있으면 실행 도구 설정만으로 얻을 수 있다.
- 사용자 흉내: React Testing Library는 내부 동작 대신 사용자 관점으로 테스트하도록 설계돼, 태그와 alt 속성과 텍스트로 요소를 찾고 이벤트를 일으킨 뒤 눈에 보이는 결과를 확인한다.
- 선택자 원칙: className이나 id는 리팩터링에서 쉽게 바뀌고 사용자 관점에서 중요하지 않아 권장하지 않으며, 필요하면 시맨틱 태그나 ARIA로 바꾸는 편이 낫다.
- 예외 처리: 그래도 식별자가 필요하면 data-testid를 써서 그 요소가 테스트에 중요하다는 것을 드러낸다.
- 비동기 처리: 대부분의 로직이 비동기이므로 findByText나 userEvent 계열 함수를 await로 다루도록 설계돼 있다.
- 서버 흉내: 실제 서버에 붙지 않고 MSW로 응답을 모방하며, 스토리북 애드온으로 스토리마다 목을 지정할 수 있다.
- 목 관리의 어려움: API 호출이 불규칙하고 페이지마다 추적하지 않아 시간이 지날수록 관리가 어려워졌고, 파트너센터는 공통 목을 한 곳에 모아 프로젝트 전체에서 공유하는 방향으로 바꿨다.
- 목의 함정: 목이 localStorage를 제어하는데 테스트가 그 값을 검증한다면 컴포넌트가 아니라 목을 테스트하는 셈이 되므로 목의 로직이 복잡해지는 것을 경계한다.
왜 읽나테스트를 쓰기로 정했는데 유닛과 통합 중 무엇을 어디에 두고 무엇으로 흉내낼지 막막하다면 도구 선택과 작성 패턴이 예제 단위로 정리돼 있다.