[오즈의 제작소 NINJA] TDD (3)

16257 단어 TDDprojectTDD

Jest를 이용한 Snapshot Testing

snapshot testing

스냅샷 테스팅(snapshot testing)이란 어떤 기능의 예상 결과를 미리 정확히 포착해두고 실제 결과에 비교하는 테스트 기법입니다. 테스트 대상 기능의 구현이 변경되어 실제 결과과 스냅샷을 떠놓은 예상 결과와 달라질 경우 해당 테스트 케이스는 실패하게 되는데요.이럴 경우, 다시 새로운 스냅샷을 떠서 기존 스냅샷을 교체하는 방식으로 테스트 코드와 함께 스냅샷도 함께 유지보수를 합니다.

예를 들어, 어떤 사진을 찍는 다고 가정하자. 찍기전에 어떻게 찍힐 지 내 머릿속의 이미지를 촬영해놓는다(가정). 그 다음 사진을 찍고 이전에 촬영된 머릿속 이미지 사진과 비교한다. 서로 다르다면 테스트 케이스는 실패!. 새로운 스냅샷을 따서 기존 스냅샷을 교체 후 다시 진행

inline snapshot by jest

// repeat.js

function repeat(word, times = 2) {
  let words = [];
  for (let i = 0; i < times; i++) {
    words.push(word);
  }
  return words;
}

export default repeat;
// repeat.test.js

import repeat from "./repeat";

test("repeats words three times", () => {
  expect(repeat("Test", 3)).toMatchInlineSnapshot();
});

이 테스트 코드를 실행해보면 테스트 케이스가 통과하게되고, 하나의 스냅샷에 써졌다는 메세지가 표시됨.


그럼 이 스냅샷은 어디에 작성된걸까?

// repeat.test.js

import repeat from "./repeat";

test("repeats words three times", () => {
  expect(repeat("Test", 3)).toMatchInlineSnapshot(`
    Array [
      "Test",
      "Test",
      "Test",
    ]
  `);
});

다음과 같이 기존의 파일에 인라인으로 스냅샷이 작성되었다. Jest가 해줌.

inline snapshot 갱신 by jest

기존의 repeat.js 파일을 바꾸어보자

// repeat.js

function repeat(word, times = 2) {
  let words = [];
  for (let i = 0; i < times; i++) {
    words.push(word);
  }
  return words.join(); // 베열 대신 문자열 반환
}

export default repeat;

그러고 난 후 테스트해보면, 당연히 테스트 케이스는 실패한다. 스냅샷과 다르므로

다음과 같이 피드백자세히 온다.

-u 옵션을 주어 jest를 실행하면?

$ npx jest -u
// repeat.test.js

import repeat from "./repeat";

test("repeats words three times", () => {
  expect(repeat("Test", 3)).toMatchInlineSnapshot(`"Test,Test,Test"`);
});

스냅샷이 갱신된다.

inline snapshot을 일반 테스트로

jestmatcher함수를 사용하면된다.

// repeat.test.js

import repeat from "./repeat";

test("repeats words three times", () => {
  expect(repeat("Test", 3)).toEqual("Test,Test,Test");
});

File Snapshot by Jest

스냅샷이 길거나 복잡한 경우에는 테스트 파일 안에 스냅샷을 함께 두는 것보다는 별도의 파일에 관리하는 것이 용이합니다. 스냅샷을 따로 파일로 관리하기위하여.

주로 jesttoMatchSnapshot()을 사용한다.

// repeat.test.js

import repeat from "./repeat";

test("repeats words three times", () => {
  expect(repeat("Test", 3)).toMatchSnapshot();
});

테스트하면 스냅샷이 생성된다. 테스트 파일이 위치하는 경로에 snapshots 디렉토리가 생성되고, 그 안에 repeat.test.js.snap 파일이 생길 것입니다.

// Jest Snapshot v1, https://goo.gl/fbAQLP
// __snapshots__/repeat.test.js.snap## File Snapshot 갱신


exports[`repeats words three times 1`] = `"Test,Test,Test"`;

File Snapshot 갱신

다음과 같이 repeat.js를 갱신해보자

// repeat.js

function repeat(word, times = 2) {
  let words = [];
  for (let i = 0; i < times; i++) {
    words.push(word);
  }
  return words; // 문자열 대신 배열 반환
}

export default repeat;

테스트를 실행해보면 실패! 스냅샷과 다르기 때문.
마찬가지로 npm run jest -u를 실행하면 다시 스냅샷이 갱신된다.

// __snapshots__/repeat.test.js.snap
exports[`repeats words three times 1`] = `
Array [
  "Test",
  "Test",
  "Test",
]
`;

정리

이상으로 Jest를 이용하여 어떻게 인라인 스냅샷과 파일 스냅샷 테스틩을 할 수 있는지에 대해서 살펴보았습니다. 스냅샷 테스팅은 어떤 함수의 예상 결과를 직접 코딩하지 않아도 되는 편리함이 있지만, 무분별하게 사용할 경우 스냅샷 자체의 유지보수가 어려워지는 부작용도 있습니다. 따라서, 테스트의 예상 결과를 개발자가 직접 작성하는데 시간과 노력이 많이 들어가는 경우에만 제한적으로 사용하시기를 권장드립니다.

😆 어떤 함수의 예상 결과를 직접 코딩하지 않아도 되는 편리함이 있다. Jest가 스냅샷 만들어주니깐

😭 하지만 무분별하게 사용되면 오히려 유지보수가 어렵다.

예상 결과를 직접 작성하는데 오래 걸릴거 같으면 쓰자

Reference

좋은 웹페이지 즐겨찾기