공지
뉴스레터 발행 주기를 주 3회로 변경합니다.

하드 스킬

0046. Vitest에서의 스냅샷 테스트 개념과 활용

리액트 애플리케이션을 제작하다보면, 컴포넌트의 UI 구조가 예상치 못하게 바뀌어버리는 상황을 미리 파악하는 일이 중요한 경우가 있습니다. 스냅샷 테스트(Snapshot Test)는 컴포넌트가 렌더링해내는 결과물(주로 DOM 구조)을 파일 형태로 보관하고, 테스트 실행 시 새로 생성된 결과물과 비교해 차이점을 확인하여 UI 변경 여부를 빠르게 감지 하는 데 사용됩니다. 의도된 변경인지 의도하지 않은 버그인지 파악하기에 좋지요.

2024.12.23 | 조회 352 |
0
|
from.
푸딩캠프
푸딩캠프의 프로필 이미지

푸딩캠프

주 3회, 하드스킬, 소프트스킬, 멘토링과 코칭 사례를 다루는 콘텐츠로 여러분의 학습과 성장을 돕습니다.

푸딩캠프 이야기

토이스토리 1기 2차 프로젝트 운영 시작

드디어 토이스토리 1기의 2차 프로젝트의 개발 기간 8주를 지나 운영 기간에 접어듭니다. 2주 동안 진행될 예정이었으나 2주 운영 기간에 휴일이 많아 예외적으로 3주 동안 진행하지요. 1차 프로젝트를 발전시킨 팀이 있는가 하면 전혀 다른 새 프로젝트를 개발한 팀도 있어요.

뉴스레터를 통해 여러분께 프로젝트를 소개해드릴게요. 애정을 갖고 사용하시고 피드백도 전해주세요. :)

 

Vitest에서의 스냅샷 테스트 개념과 활용

리액트 애플리케이션을 제작하다보면, 컴포넌트의 UI 구조가 예상치 못하게 바뀌어버리는 상황을 미리 파악하는 일이 중요한 경우가 있습니다. 스냅샷 테스트(Snapshot Test)는 컴포넌트가 렌더링해내는 결과물(주로 DOM 구조)을 파일 형태로 보관하고, 테스트 실행 시 새로 생성된 결과물과 비교해 차이점을 확인하여 UI 변경 여부를 빠르게 감지 하는 데 사용됩니다. 의도된 변경인지 의도하지 않은 버그인지 파악하기에 좋지요. 우리가 사용하는 Vitest는 Jest와 유사한 스냅샷 테스트 기능을 제공합니다.

 

(1) 스냅샷 테스트란?

스냅샷 테스트는 컴포넌트 단위 테스트나 통합 테스트와 달리, UI 상태 자체를 문자열 형태로 기록한다는 점이 특징입니다. 예를 들어, Subscription 컴포넌트가 렌더링하는 <input> 태그와 <button> 태그가 어떤 속성을 갖고 있는지, 자식 엘리먼트로 어떤 텍스트가 들어가는지를 전부 파일(주로 .snap 확장자)에 저장해둡니다. 이후 테스트를 재실행할 때, Vitest가 “방금 렌더링된 DOM 구조”와 “기존 스냅샷 파일”을 비교하여 한 글자라도 달라지면 테스트를 실패 처리합니다.이런 방식은 의도된 변경(예: 버튼 라벨을 '구독하기'에서 '신청하기'로 바꿈)과 의도되지 않은 변경(버그로 인해 필요 없는 태그가 추가되거나 스타일이 깨짐)을 빠르게 구별하는 데 매우 유용합니다. 변경 사항이 있어도 당연히 바꿔야 하는 부분이라고 확신할 수 있다면 스냅샷을 업데이트하면 되지만, 예상 밖의 부분이 달라졌다면 즉시 개발자가 확인해볼 수 있는 지표가 됩니다.스냅샷 테스트의 장점은 UI 변경 이력이 또렷하게 드러난다는 것이고, 단점은 UI가 너무 자주 바뀌는 경우, 스냅샷이 자꾸 깨져서 번거롭게 느껴질 수 있다는 점입니다. 그러므로 변경이 잦지 않은 핵심 UI 구조를 위주로 스냅샷을 생성하고, 자주 변하는 영역은 다른 방식의 테스트(React Testing Library의 쿼리 기반 테스트 등)를 활용하는 것이 좋습니다. 이를테면, 회원가입 폼은 변경이 잦진 않지만 중요한 페이지이므로 스냅샷 테스트의 주요한 대상이 됩니다.

 

(2) Vitest에서 스냅샷 테스트 작성하기

리액트 컴포넌트를 테스트할 때는 @testing-library/react를 사용해 가상 DOM에 해당 컴포넌트를 렌더링한 뒤, 그 결과(container)를 스냅샷으로 기록합니다. 아래 예시는 Subscription 컴포넌트에 대한 스냅샷 테스트를 작성한 코드입니다.

 
 

이 코드는 지금까지 우리가 작성한 Subscription 컴포넌트입니다. 다음은 Subscription.test.jsx 내용에 새로이 스냅샷 테스트를 추가한 것입니다.

 
 

테스트를 실행하면, 프로젝트 내에 __snapshots__ 디렉터리나 테스트 파일과 동일한 위치에 .snap 파일이 자동으로 생성됩니다. 이 파일에는 container에 포함된 DOM 구조 전체가 문자열로 들어가며, 예를 들어 <div><input ... /><button ...>구독하기</button></div>와 같은 형태로 기록됩니다. 다음은 스냅샷 파일 예시입니다.

 
 

이후 버튼 라벨이나 자식 텍스트가 달라지면, Vitest가 스냅샷 비교 결과가 다르다고 알려주면서 “어떤 부분이 바뀌었는지”를 확인할 수 있도록 돕습니다. 만약 이것이 의도된 변경이라면, vitest --updateSnapshot 명령(또는 vitest -u)을 통해 스냅샷 파일을 갱신하면 됩니다. 반대로 변경이 의도되지 않은 것으로 판명되면, 해당 시점에서 바로 버그를 파악해 수정할 수 있습니다.

 

(3) 불필요하게 자주 깨지는 스냅샷 테스트에 대한 대처법

스냅샷 테스트가 편리한 반면, 컴포넌트 구조가 자주 바뀌는 환경이라면 지나치게 쉽게 깨질 수 있습니다. 이 경우 의도된 수정인지, 아니면 버그인지를 매번 확인하고 스냅샷을 업데이트하거나, 코드를 되돌려야 하므로 테스트 유지 비용이 커질 수 있습니다. 다음과 같은 전략들을 사용해 스냅샷 테스트가 과도하게 깨지는 문제를 완화할 수 있습니다.

1) 무작위 값이나 날짜/시간 처리 시 Mocking

컴포넌트가 현재 시각을 표시하거나, 무작위 난수를 생성해 DOM 구조를 바꾼다면, 스냅샷이 매 실행마다 달라집니다. 이럴 땐 Vitest의 vi.useFakeTimers(), vi.fn() 등을 통해 해당 부분을 Mock 처리하여 일정한 값이 들어가도록 만듭니다.

2) 스냅샷 범위 최소화

너무 거대한 컴포넌트 전체를 스냅샷으로 찍으면, 작은 부분 하나만 변경되어도 전체가 깨집니다. 만약 UI가 자주 변하는 일부 영역은 제외하고, 상대적으로 안정적인 부모 레이아웃 구조만 스냅샷을 찍을 수도 있습니다. 또는 스냅샷이 아닌 RTL의 쿼리 기반 테스트(getByText, getByRole 등)를 이용해 필요한 요소만 검증할 수도 있습니다.

3) 스냅샷을 “검증 포인트”로 적절히 활용

스냅샷이 항상 깨지는 상황이라면, 그 부분은 사용자 이벤트 테스트나 E2E 테스트로 대체하는 것도 방법입니다. 예컨대 “버튼을 클릭하면 modal이 열리는지” 정도는 스냅샷보다는 사용자 상호작용 관점에서 테스트하는 것이 더 의미가 큽니다.이렇듯 스냅샷 테스트는 UI 변경 이력을 빠르게 추적하는 용도로는 탁월하지만, 너무 자주 업데이트해야 하거나 구조가 크게 달라지면 번거로워질 수 있습니다. 따라서 특정 컴포넌트가 “이 레이아웃과 태그 구조는 거의 변하지 않는다”라고 판단될 때 스냅샷을 적용하는 식으로, 선택과 집중을 해보는 것이 이상적입니다.

 

(4) 정리

Vitest의 스냅샷 테스트는 리액트 UI가 의도치 않게 변형되었는지 모니터링하는 도구입니다. 특히, 팀 단위 협업 시 “분명히 수정하지 않았다고 생각했던 부분이 바뀌었다”는 문제가 발생하면, 스냅샷 테스트가 즉시 해당 변화를 감지해 줍니다. 다만, 스냅샷 관리 비용이 커질 수 있으므로 자주 변하는 UI 요소보다는 안정적인 영역 위주로 적용하고, 날짜나 무작위성 같은 요소는 미리 Mock 처리하여 테스트가 매번 일정한 결과를 내도록 설계하는 것이 좋습니다. 이렇게 하면 스냅샷 테스트가 코드 품질과 협업 효율을 높이는 데 도움이 될 것입니다.


푸딩캠프 뉴스레터가 유익하셨나요? 주변에 소개해주세요. 뉴스레터 구독자 수는 더 좋은 컨텐츠를 만드는 원동력입니다.

뉴스레터 관련하여 문의나 건의는 이 이메일 주소인 newsletter@puddingcamp.com 로 답장을 보내시면 됩니다.

또한 한날과 커피챗은 언제든 열려있고 환영합니다. https://puddingcamp.com/coffeechat 에 방문하셔서 커피챗 일정을 잡아보세요!

다가올 뉴스레터가 궁금하신가요?

지금 구독해서 새로운 레터를 받아보세요

✉️

이번 뉴스레터 어떠셨나요?

푸딩캠프 님에게 ☕️ 커피와 ✉️ 쪽지를 보내보세요!

댓글

의견을 남겨주세요

확인
의견이 있으신가요? 제일 먼저 댓글을 달아보세요 !

다른 뉴스레터

© 2024 푸딩캠프

주 3회, 하드스킬, 소프트스킬, 멘토링과 코칭 사례를 다루는 콘텐츠로 여러분의 학습과 성장을 돕습니다.

뉴스레터 문의newsletter@puddingcamp.com

메일리 로고

자주 묻는 질문 서비스 소개서 오류 및 기능 관련 제보

서비스 이용 문의admin@team.maily.so

메일리 사업자 정보

메일리 (대표자: 이한결) | 사업자번호: 717-47-00705 | 서울 서초구 강남대로53길 8, 8층 11-7호

이용약관 | 개인정보처리방침 | 정기결제 이용약관 | 라이선스