Tech

Diary

Lecture

About Me

개발중

스냅샷 테스트

JeongSeulho

2024년 01월 19일

준비중...
클립보드로 복사

0. 들어가며

스냅샷 테스트란 무엇이며, FE에서 스냅샷 테스트를 어떻게 적용할 수 있을까?

1. 스냅샷 테스트란?

UI 컴포넌트의 렌더링 결과 또는 함수의 반환값을 저장해두었다가, 이후에 동일한 결과가 나오는지 확인하는 테스트
이때 저장시 직렬화된 문자열 형태로 저장되며, 이를 스냅샷이라고 함

2. UI 스냅샷 테스트

(1) 스냅샷 테스트 코드 작성

copy
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) 첫 스냅샷 테스트 실행 및 스냅샷 저장

  • 스냅샷 테스트를 실행하면 다음과 같이 결과가 직렬화되어 저장 됨
copy
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은 아래와 같이 별도 파일을 생성해 저장
copy
// __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 컴포넌트 뿐만 아니라 함수의 반환값에 대해서도 테스트 할 수 있다.
주로 함수의 반환값이 복잡한 경우, 스냅샷 테스트를 하면 편리하다.

copy
  it('단일 인자로 전달된 키의 값을 객체에 담아 반환한다(snapshots)', () => {
    const obj = {
      a: 'A',
      b: { c: 'C' },
      d: null,
    };

    expect(pick(obj, 'a')).toMatchInlineSnapshot(`
      {
        "a": "A",
      }
    `);
  });

검증해야할 키가 많아질 경우 스냅샷 테스트시 다른 Matcher를 사용하는 것 보다 직렬화된 문자열을 통해 검증하는 것이 편리하다.

3. 스냅샷 테스트 한계

  1. 간단한 DOM 구조에만 적용 가능
  • 너무 길어지는 코드에 가독성 저하
  1. 휴먼 에러 발생
  • u를 눌러 새로운 스냅샷을 기존 스냅샷으로 변경만 하면 테스트가 통과되어 버리면서 개인에 따라 무분별하게 스냅샷이 변경될 수 있음
  1. 실제 UI 렌더링은 테스트 불가능
  • CSS로 인해 UI가 변경되는 경우는 실제 렌더링시에만 확인 가능하며 스냅샷 테스트로는 확인 불가능
  1. TDD 방식의 테스트에 맞지 않음
  • 스냅샷 테스트의 TDD를 위한 문자열을 직접 작성하는 것은 거의 불가능