본문으로 바로가기

https://jestjs.io/docs/snapshot-testing

 

Snapshot Testing · Jest

Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly.

jestjs.io

 

snapshot이란 무엇인가?

성공한 케이스를 사진처럼 찍어서 저장해두고, 해당 케이스와 일치하는 지를 체킹하는 것입니다. 그래서 UI가 혹여나 예측할 수 없게 바뀌었는지 확인하는데 유용합니다.

 

이 외에도 직접적으로 느낄 수 있는 snapshot test의 장점은, 함수의 결과값을 가지고 자동으로 반환되어야 할 값으로 지정해준다는 것입니다. 함수의 결과를 출력하고 해당 값을 toEqual로 다시 복붙하는 등의 작업을 하지 않아도 된다는 것입니다.

 

우선 UI와 별도로, snapshot test을 이해하기 위해서 별도의 예시를 살펴보도록 하겠습니다.

 

inline snapshot, __snapshot__, etc...

아래는 글자를 reverse해서 반환하는 함수인데, 이러한 함수를 테스트하기 위해서 역순으로 글자를 일일이 타이핑해야 하는 것은 꽤나 힘들 겁니다. hello와 같이 간단한 문자가 아닙니다. welcometoyaworldbro 같은거면 상당히 고역이죠.

이 경우 toMatchInlineSnapshot를 사용하여 인라인 스냅샷을 사용하여 편리하게 참이 되는 값을 자동으로 부여할 수 있습니다.

function makeFlip(word) {
  return [...word].reverse().join('');
}

test('should reverse', () => {
  return expect(makeFlip('hello')).toBe('olleh');
});
// 테스트 구동 전
test('should reverse', () => {
  return expect(makeFlip('welcomtoyaworldbro')).toMatchInlineSnapshot();
});

// 테스트 구동 후, 자동으로 참이 되도록 snapshot을 만들어줌.
test('should reverse', () => {
  return expect(makeFlip('welcomtoyaworldbro')).toMatchInlineSnapshot(`"orbdlrowayotmoclew"`);
});

 

만약 주어진 값이 달라져서 다시 inline snapshot을 만들어야 한다면 u 옵션을 준 jest 명령어를 통해서 다시 스냅샷을 뜰 수 있습니다.

jest [test path] -u // u 옵션을 통해 스냅샷을 다시 뜰 수 있음.

 

toMatchSnapshot()을 사용하면 __snapshot__ 폴더 내에 스냅샷이 별도로 저장되고, 다음부터 해당 스냅샷과 일치하는지 테스트하게 됩니다.

test('should reverse', () => {
  return expect(makeFlip('welcomtoyaworldbro')).toMatchSnapshot();
});

 

다음과 같이요.

 

 

UI 테스팅을 위한 snapshot test

 

RTL과 함께 사용됩니다. 

import { render, screen } from "@testing-library/react"
import Hello from "./Hello"

const darren = {
    name: "darren",
    age: 26
}

const martin = {
    age: 13
}

// 최초면 스냅샷을 하나 찍음, 다음부터 스냅샷과 일치하는지 확인
test('snapshot : name이 있음', () => {
    const element = render(<Hello user={darren} />)
    expect(element).toMatchSnapshot();
});

// 최초면 스냅샷을 하나 찍음, 다음부터 스냅샷과 일치하는지 확인
test('snapshot : name이 없음', () => {
    const element = render(<Hello user={martin} />)
    expect(element).toMatchSnapshot();
});

// 그냥 RTL를 통한 테스트
test('Hello라는 글자가 있는가?', () => {
    render(<Hello user={darren} />)
    const helloEl = screen.getByText(/Hello/i);
    expect(helloEl).toBeInTheDocument();
})

 

해당 조건에 맞는 DOM을 그냥 찍는다면, 시간에 따라 값이 달라지는 컴포넌트도 있을 것입니다.

function Timer() {
  const now = Date.now();
  const sec = new Date(now).getSeconds();

  return <p>현재 {sec}초 입니다.</p>;
}

export default Timer;

 

이 경우 매번 달라지는 녀석을 mock 해버리면 됩니다.

test('초를 표시', () => {
    Date.now = jest.fn();
    Date.now.mockReturnValue = 1234;
    const el = render(<Timer />);
    expect(el).toMatchSnapshot();
})

 

 

ref)

https://www.youtube.com/watch?v=g4rMWtPNOr8

https://jestjs.io/docs/snapshot-testing

https://mulder21c.github.io/jest/docs/en/next/snapshot-testing


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체