Skip to content
Vitest 1
Main Navigation 가이드API구성고급
1.6.1
0.34.6

한국어

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
Italiano
Polski
Türkçe
čeština
magyar

한국어

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
Italiano
Polski
Türkçe
čeština
magyar

외관

Sidebar Navigation

가이드

Vitest를 선택하는 이유

시작하기

기능

워크스페이스

명령줄 인터페이스

테스트 필터링

리포터

커버리지

스냅샷

모의화

타입 테스트

Vitest UI

브라우저 모드

소스 내 테스트

테스트 컨텍스트

테스트 환경

Matcher 확장하기

IDE 통합

디버깅

다른 테스트 러너와의 비교

마이그레이션 가이드

일반적인 오류

성능 향상

API

테스트 API 참조

Mock 함수

Vi

expect

expectTypeOf

assert

assertType

구성

Vitest 구성 파일 관리

Vitest 구성하기

이 페이지에서

스냅샷 ​

Vue School 비디오 강좌로 스냅샷 배우기

스냅샷 테스트는 함수의 결과가 예상치 않게 변경되지 않았는지 확인하는 데 유용한 도구입니다.

스냅샷을 사용하면 Vitest는 주어진 값의 스냅샷을 생성하고, 이를 테스트와 함께 저장된 참조 스냅샷 파일과 비교합니다. 두 스냅샷이 일치하지 않으면 테스트가 실패합니다. 이는 예상치 못한 변경이 발생했거나, 참조 스냅샷을 새로운 결과 버전으로 업데이트해야 함을 의미합니다.

스냅샷 사용 ​

값을 스냅샷으로 만들려면 expect() API에서 toMatchSnapshot()를 사용합니다.

ts
function toUpperCase(str: string) {
  return str;
}
// ---cut---
import { expect, it } from 'vitest';

it('toUpperCase', () => {
  const result = toUpperCase('foobar');
  expect(result).toMatchSnapshot();
});

이 테스트를 처음 실행하면 Vitest는 다음과 같은 스냅샷 파일을 생성합니다.

js
// Vitest Snapshot v1, https://www.getbook.com/ko/book/vitest-1/guide/snapshot

exports['toUpperCase 1'] = '"FOOBAR"';

스냅샷 파일은 코드 변경 사항과 함께 커밋되어 코드 검토 과정에서 함께 검토해야 합니다. 이후 테스트 실행 시 Vitest는 렌더링된 결과를 이전 스냅샷과 비교합니다. 일치하면 테스트가 통과됩니다. 일치하지 않는다면, 테스트 실행기는 코드에서 수정해야 할 버그를 발견했거나, 구현 변경으로 인해 스냅샷 업데이트가 필요함을 나타냅니다.

WARNING

비동기 동시 테스트와 함께 스냅샷을 사용하는 경우, 올바른 테스트가 감지되도록 로컬 테스트 컨텍스트의 expect를 사용해야 합니다.

인라인 스냅샷 ​

toMatchInlineSnapshot()를 사용하여 스냅샷을 테스트 파일 내에 직접 저장할 수도 있습니다.

ts
function toUpperCase(str: string) {
  return str;
}
// ---cut---
import { expect, it } from 'vitest';

it('toUpperCase', () => {
  const result = toUpperCase('foobar');
  expect(result).toMatchInlineSnapshot();
});

스냅샷 파일을 만드는 대신 Vitest는 테스트 파일을 직접 수정하여 스냅샷을 문자열로 업데이트합니다.

ts
function toUpperCase(str: string) {
  return str;
}
// ---cut---
import { expect, it } from 'vitest';

it('toUpperCase', () => {
  const result = toUpperCase('foobar');
  expect(result).toMatchInlineSnapshot('"FOOBAR"');
});

이렇게 하면 다른 파일을 오가며 확인하지 않고도 예상 결과를 즉시 확인할 수 있습니다.

WARNING

비동기 동시 테스트와 함께 스냅샷을 사용하는 경우, 올바른 테스트가 감지되도록 로컬 테스트 컨텍스트의 expect를 사용해야 합니다.

스냅샷 업데이트 ​

반환된 값이 스냅샷과 일치하지 않으면 테스트는 실패하고, 두 값의 차이를 보여줍니다. 스냅샷 변경이 예상되는 경우, 현재 상태로 스냅샷을 업데이트할 수 있습니다.

감시(watch) 모드에서는 터미널에서 u 키를 눌러 실패한 스냅샷을 직접 업데이트할 수 있습니다.

또는 CLI에서 --update 또는 -u 플래그를 사용하여 Vitest가 스냅샷을 업데이트하도록 할 수 있습니다.

bash
vitest -u

파일 스냅샷 ​

toMatchSnapshot()을 호출하면 모든 스냅샷이 포맷된 .snap 파일에 저장됩니다. 즉, 스냅샷 문자열 내의 특정 문자(특히 큰따옴표 " 및 백틱 ```)는 이스케이프 처리해야 합니다. 또한 스냅샷 콘텐츠에 대한 구문 강조 표시가 손실될 수 있습니다(일부 언어의 경우).

이러한 경우를 개선하기 위해 파일에 명시적으로 스냅샷을 저장할 수 있도록 toMatchFileSnapshot()를 도입했습니다. 이를 통해 스냅샷 파일에 파일 확장자를 지정하고 더 읽기 쉽게 만들 수 있습니다.

ts
import { expect, it } from 'vitest';

it('render basic', async () => {
  const result = renderHTML(h('div', { class: 'foo' }));
  await expect(result).toMatchFileSnapshot('./test/basic.output.html');
});

./test/basic.output.html의 내용과 비교하고, --update 플래그로 다시 쓸 수 있습니다.

이미지 스냅샷 ​

jest-image-snapshot을 사용하여 이미지 스냅샷을 생성할 수도 있습니다.

bash
npm i -D jest-image-snapshot
ts
test('image snapshot', () => {
  expect(readFileSync('./test/stubs/input-image.png')).toMatchImageSnapshot();
});

examples/image-snapshot 예제에서 자세히 알아볼 수 있습니다.

사용자 정의 Serializer ​

스냅샷이 직렬화되는 방식을 변경하기 위해 자체 로직을 추가할 수 있습니다. Jest와 마찬가지로 Vitest에는 기본 JavaScript 유형, HTML 요소, ImmutableJS 및 React 요소에 대한 기본 serializer가 포함되어 있습니다.

expect.addSnapshotSerializer API를 사용하여 사용자 지정 직렬 변환기를 명시적으로 추가할 수 있습니다.

ts
expect.addSnapshotSerializer({
  serialize(val, config, indentation, depth, refs, printer) {
    // `printer`는 기존 플러그인을 사용하여 값을 직렬화하는 함수입니다.
    return `Pretty foo: ${printer(val.foo, config, indentation, depth, refs)}`;
  },
  test(val) {
    return val && Object.prototype.hasOwnProperty.call(val, 'foo');
  },
});

사용자 지정 직렬 변환기를 암시적으로 추가하는 snapshotSerializers 옵션도 지원합니다.

ts
import { SnapshotSerializer } from 'vitest';

export default {
  serialize(val, config, indentation, depth, refs, printer) {
    // `printer`는 기존 플러그인을 사용하여 값을 직렬화하는 함수입니다.
    return `Pretty foo: ${printer(val.foo, config, indentation, depth, refs)}`;
  },
  test(val) {
    return val && Object.prototype.hasOwnProperty.call(val, 'foo');
  },
} satisfies SnapshotSerializer;
ts
import { defineConfig } from 'vite';

export default defineConfig({
  test: {
    snapshotSerializers: ['path/to/custom-serializer.ts'],
  },
});

다음과 같은 테스트를 추가한 후:

ts
test('foo snapshot test', () => {
  const bar = {
    foo: {
      x: 1,
      y: 2,
    },
  };

  expect(bar).toMatchSnapshot();
});

다음 스냅샷을 얻게 됩니다.

Pretty foo: Object {
  "x": 1,
  "y": 2,
}

스냅샷 직렬화에는 Jest의 pretty-format이 사용됩니다. 자세한 내용은 pretty-format에서 확인할 수 있습니다.

Jest와의 차이점 ​

Vitest는 몇 가지 예외를 제외하고 Jest와 거의 호환되는 스냅샷 기능을 제공합니다.

1. 스냅샷 파일의 주석 헤더가 다릅니다. {#_1-comment-header-in-the-snapshot-file-is-different} ​

diff
- // Jest Snapshot v1, https://goo.gl/fbAQLP
+ // Vitest Snapshot v1, https://www.getbook.com/ko/book/vitest-1/guide/snapshot

이는 기능에 실제로 영향을 미치지는 않지만, Jest에서 마이그레이션할 때 커밋 diff에 영향을 줄 수 있습니다.

2. printBasicPrototype의 기본값은 false입니다. {#_2-printbasicprototype-is-default-to-false} ​

Jest와 Vitest의 스냅샷은 모두 pretty-format으로 구동됩니다. Vitest는 더 깔끔한 스냅샷 출력을 위해 printBasicPrototype의 기본값을 false로 설정했습니다. 반면 Jest 29.0.0 미만 버전에서는 기본값이 true입니다.

ts
import { expect, test } from 'vitest';

test('snapshot', () => {
  const bar = [
    {
      foo: 'bar',
    },
  ];

  // in Jest
  expect(bar).toMatchInlineSnapshot(`
    Array [
      Object {
        "foo": "bar",
      },
    ]
  `);

  // in Vitest
  expect(bar).toMatchInlineSnapshot(`
    [
      {
        "foo": "bar",
      },
    ]
  `);
});

이것이 가독성과 전반적인 DX에 더 합리적인 기본값이라고 생각합니다. 여전히 Jest의 동작을 선호하는 경우, 구성을 변경할 수 있습니다.

ts
// vitest.config.js
export default defineConfig({
  test: {
    snapshotFormat: {
      printBasicPrototype: true,
    },
  },
});

3. 사용자 정의 메시지의 경우 콜론 : 대신 셰브론 >이 구분 기호로 사용됩니다. {#_3-chevron-is-used-as-a-separator-instead-of-colon-for-custom-messages} ​

사용자 정의 메시지를 사용할 때, 콜론(:) 대신 셰브론 기호(>)가 구분자로 사용됩니다.

다음 예제 테스트 코드의 경우:

js
test('toThrowErrorMatchingSnapshot', () => {
  expect(() => {
    throw new Error('error');
  }).toThrowErrorMatchingSnapshot('hint');
});

Jest에서 스냅샷은 다음과 같습니다.

console
exports[`toThrowErrorMatchingSnapshot: hint 1`] = `"error"`;

Vitest에서 해당하는 스냅샷은 다음과 같습니다.

console
exports[`toThrowErrorMatchingSnapshot > hint 1`] = `[Error: error]`;

4. toThrowErrorMatchingSnapshot 및 toThrowErrorMatchingInlineSnapshot의 기본 Error 스냅샷이 다름 {#_4-default-error-snapshot-is-different-for-tothrowerrormatchingsnapshot-and-tothrowerrormatchinginlinesnapshot} ​

js
import { expect, test } from 'vitest';
// ---cut---
test('snapshot', () => {
  //
  // in Jest
  //

  expect(new Error('error')).toMatchInlineSnapshot(`[Error: error]`);

  // Jest는 `Error` 인스턴스에 대해 `Error.message` 스냅샷을 생성합니다.
  expect(() => {
    throw new Error('error');
  }).toThrowErrorMatchingInlineSnapshot(`"error"`);

  //
  // in Vitest
  //

  expect(new Error('error')).toMatchInlineSnapshot(`[Error: error]`);

  expect(() => {
    throw new Error('error');
  }).toThrowErrorMatchingInlineSnapshot(`[Error: error]`);
});
Pager
이전커버리지
다음모의화

MIT 라이선스 하에 배포되었습니다.

Copyright (c) 2024 Mithril Contributors

https://v1.vitest.dev/guide/snapshot

MIT 라이선스 하에 배포되었습니다.

Copyright (c) 2024 Mithril Contributors