스냅샷 테스트
JeongSeulho
2024년 01월 19일
준비중...
클립보드로 복사
0. 들어가며
스냅샷 테스트란 무엇이며, FE에서 스냅샷 테스트를 어떻게 적용할 수 있을까?
1. 스냅샷 테스트란?
UI 컴포넌트의 렌더링 결과 또는 함수의 반환값을 저장해두었다가, 이후에 동일한 결과가 나오는지 확인하는 테스트
이때 저장시 직렬화된 문자열 형태로 저장되며, 이를 스냅샷이라고 함
2. UI 스냅샷 테스트
(1) 스냅샷 테스트 코드 작성
import PageTitle from '@/pages/cart/components/PageTitle';
import render from '@/utils/test/render';
it('pageTitle 스냅샷 테스트(toMatchInlineSnapshot)', async () => {
const { container } = await render(<PageTitle />);
expect(container).toMatchInlineSnapshot();
});
it('pageTitle 스냅샷 테스트(toMatchSnapshot)', async () => {
const { container } = await render(<PageTitle />);
expect(container).toMatchSnapshot();
});
toMatchInlineSnapshot
: 직렬화된 문자열을 테스트 파일에 저장toMatchSnapshot
: 직렬화된 문자열을 별도 파일을 생성해 저장
(2) 첫 스냅샷 테스트 실행 및 스냅샷 저장
- 스냅샷 테스트를 실행하면 다음과 같이 결과가 직렬화되어 저장 됨
import PageTitle from '@/pages/cart/components/PageTitle';
import render from '@/utils/test/render';
it('pageTitle 스냅샷 테스트(toMatchInlineSnapshot)', async () => {
const { container } = await render(<PageTitle />);
expect(container).toMatchInlineSnapshot(`
<div>
<h1
class="MuiTypography-root MuiTypography-h4 css-1lnl64-MuiTypography-root"
>
상품 리스트
</h1>
<div
style="position: fixed; z-index: 9999; top: 16px; left: 16px; right: 16px; bottom: 16px; pointer-events: none;"
/>
</div>
`);
});
it('pageTitle 스냅샷 테스트(toMatchSnapshot)', async () => {
const { container } = await render(<PageTitle />);
expect(container).toMatchSnapshot();
});
toMatchSnapshot
은 아래와 같이 별도 파일을 생성해 저장
// __snapshots__/PageTitle.spec.jsx.snap
exports[`pageTitle 스냅샷 테스트(toMatchSnapshot) 1`] = `
<div>
<h1
class="MuiTypography-root MuiTypography-h4 css-1lnl64-MuiTypography-root"
>
상품 리스트
</h1>
<div
style="position: fixed; z-index: 9999; top: 16px; left: 16px; right: 16px; bottom: 16px; pointer-events: none;"
/>
</div>
`;
(3) 이후 스냅샷 테스트 실행
이후 스냅샷 테스트를 실행 시, 기존의 스냅샷과 같은지 검증한다.
이때 테스트 실패시(새롭게 생성된 스냅샷 기존의 스냅샷과 다른 경우) 새롭게 생성된 스냅샷(변경 된 스냅샷)을 기준으로 삼을지 결정한다.
2. 함수 스냅샷 테스트
스냅샷 테스트는 UI 컴포넌트 뿐만 아니라 함수의 반환값에 대해서도 테스트 할 수 있다.
주로 함수의 반환값이 복잡한 경우, 스냅샷 테스트를 하면 편리하다.
it('단일 인자로 전달된 키의 값을 객체에 담아 반환한다(snapshots)', () => {
const obj = {
a: 'A',
b: { c: 'C' },
d: null,
};
expect(pick(obj, 'a')).toMatchInlineSnapshot(`
{
"a": "A",
}
`);
});
검증해야할 키가 많아질 경우 스냅샷 테스트시 다른 Matcher
를 사용하는 것 보다 직렬화된 문자열을 통해 검증하는 것이 편리하다.
3. 스냅샷 테스트 한계
- 간단한 DOM 구조에만 적용 가능
- 너무 길어지는 코드에 가독성 저하
- 휴먼 에러 발생
u
를 눌러 새로운 스냅샷을 기존 스냅샷으로 변경만 하면 테스트가 통과되어 버리면서 개인에 따라 무분별하게 스냅샷이 변경될 수 있음
- 실제 UI 렌더링은 테스트 불가능
- CSS로 인해 UI가 변경되는 경우는 실제 렌더링시에만 확인 가능하며 스냅샷 테스트로는 확인 불가능
- TDD 방식의 테스트에 맞지 않음
- 스냅샷 테스트의 TDD를 위한 문자열을 직접 작성하는 것은 거의 불가능