Skip to content
Vitest 3
Main Navigation 가이드 & API구성브라우저 모드고급 API
3.2.0
2.1.9
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 구성하기

API

테스트 API 참조

Mock 함수

Vi

expect

expectTypeOf

assert

assertType

가이드

명령줄 인터페이스

테스트 필터링

테스트 프로젝트

리포터

커버리지

스냅샷

모킹

병렬 처리

타입 검사

Vitest UI

소스 내 테스팅

테스트 컨텍스트

테스트 어노테이션

테스트 환경

매처 확장하기

IDE 통합

디버깅

일반적인 오류

마이그레이션 가이드

Vitest 3.0으로 마이그레이션

Jest에서 마이그레이션

성능

테스트 성능 프로파일링

성능 향상

브라우저 모드

고급 API

다른 테스트 러너와의 비교

이 페이지에서

테스트 컨텍스트 ​

Playwright Fixtures에서 영감을 받은 Vitest의 테스트 컨텍스트를 사용하면 테스트에서 활용할 유틸리티, 상태 및 픽스처를 정의할 수 있습니다.

사용법 ​

각 테스트 콜백 함수의 첫 번째 인수는 테스트 컨텍스트입니다.

ts
import { it } from 'vitest';

it('should work', ({ task }) => {
  // 테스트 이름을 출력합니다.
  console.log(task.name);
});

내장 테스트 컨텍스트 ​

task ​

테스트에 대한 메타데이터를 포함하는 읽기 전용 객체입니다.

expect ​

현재 테스트에 연결된 expect API:

ts
import { it } from 'vitest';

it('math is easy', ({ expect }) => {
  expect(2 + 2).toBe(4);
});

이 API는 전역 expect가 스냅샷 테스트를 올바르게 추적하지 못하기 때문에 스냅샷 테스트를 동시에 실행하는 데 유용합니다.

ts
import { it } from 'vitest';

it.concurrent('math is easy', ({ expect }) => {
  expect(2 + 2).toMatchInlineSnapshot();
});

it.concurrent('math is hard', ({ expect }) => {
  expect(2 * 2).toMatchInlineSnapshot();
});

skip ​

ts
function skip(note?: string): never;
function skip(condition: boolean, note?: string): void;

이후 테스트 실행을 건너뛰고, 해당 테스트를 건너뛴 상태로 표시합니다.

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

it('math is hard', ({ skip }) => {
  skip();
  expect(2 + 2).toBe(5);
});

Vitest 3.1부터는 조건부로 테스트를 건너뛰기 위해 불리언 매개변수를 허용합니다.

ts
it('math is hard', ({ skip, mind }) => {
  skip(mind === 'foggy');
  expect(2 + 2).toBe(5);
});

annotate 3.2.0+ ​

ts
function annotate(
  message: string,
  attachment?: TestAttachment
): Promise<TestAnnotation>;

function annotate(
  message: string,
  type?: string,
  attachment?: TestAttachment
): Promise<TestAnnotation>;

리포터 도구에 표시될 테스트 주석을 추가합니다.

ts
test('annotations API', async ({ annotate }) => {
  await annotate('https://github.com/vitest-dev/vitest/pull/7953', 'issues');
});

signal 3.2.0+ ​

Vitest에 의해 중단될 수 있는 AbortSignal입니다. 신호는 다음과 같은 상황에서 중단됩니다.

  • 테스트 시간 초과
  • 사용자가 Ctrl+C로 테스트 실행을 수동으로 취소함
  • vitest.cancelCurrentRun이 프로그래밍 방식으로 호출됨
  • 다른 테스트가 병렬로 실패하고 bail 플래그가 설정됨
ts
it('stop request when test times out', async ({ signal }) => {
  await fetch('/resource', { signal });
}, 2000);

onTestFailed ​

현재 테스트에 연결된 onTestFailed 훅입니다. 이 API는 테스트를 동시에 실행할 때, 특정 테스트에 대해 특별한 처리가 필요할 경우 유용합니다.

onTestFinished ​

현재 테스트에 연결된 onTestFinished 훅입니다. 이 API는 테스트를 동시에 실행할 때, 특정 테스트에 대해 특별한 처리가 필요할 경우 유용합니다.

테스트 컨텍스트 확장 ​

Vitest는 테스트 컨텍스트를 확장하는 두 가지 방식을 제공합니다.

test.extend ​

Playwright와 마찬가지로 이 메서드를 사용하여 사용자 지정 픽스처로 자신만의 test API를 정의하고, 이를 어디서든 재사용할 수 있습니다.

예를 들어, 먼저 todos와 archive라는 두 개의 픽스처를 사용하여 test 객체를 생성합니다.

ts
import { test as baseTest } from 'vitest';

const todos = [];
const archive = [];

export const test = baseTest.extend({
  todos: async ({}, use) => {
    // 각 테스트 함수 전에 픽스처를 준비합니다.
    todos.push(1, 2, 3);

    // 픽스처 값을 사용합니다.
    await use(todos);

    // 각 테스트 함수 후에 픽스처를 정리합니다.
    todos.length = 0;
  },
  archive,
});

그런 다음 가져와서 사용할 수 있습니다.

ts
import { expect } from 'vitest';
import { test } from './my-test.js';

test('add items to todos', ({ todos }) => {
  expect(todos.length).toBe(3);

  todos.push(4);
  expect(todos.length).toBe(4);
});

test('move items from todos to archive', ({ todos, archive }) => {
  expect(todos.length).toBe(3);
  expect(archive.length).toBe(0);

  archive.push(todos.pop());
  expect(todos.length).toBe(2);
  expect(archive.length).toBe(1);
});

또한 test를 확장하여 더 많은 픽스처를 추가하거나 기존 픽스처를 재정의할 수 있습니다.

ts
import { test as todosTest } from './my-test.js';

export const test = todosTest.extend({
  settings: {
    // ...
  },
});

픽스처 초기화 ​

Vitest 러너는 사용량에 따라 픽스처를 스마트하게 초기화하고 테스트 컨텍스트에 주입합니다.

ts
import { test as baseTest } from 'vitest';

const test = baseTest.extend<{
  todos: number[];
  archive: number[];
}>({
  todos: async ({ task }, use) => {
    await use([1, 2, 3]);
  },
  archive: [],
});

// todos는 실행되지 않습니다.
test('skip', () => {});
test('skip', ({ archive }) => {});

// todos는 실행됩니다.
test('run', ({ todos }) => {});

WARNING

test.extend()를 픽스처와 함께 사용할 때는 픽스처 함수와 테스트 함수 모두에서 { todos }와 같은 객체 비구조화 패턴을 사용하여 컨텍스트에 접근해야 합니다.

ts
test('context must be destructured', (context) => { 
  expect(context.todos.length).toBe(2)
})

test('context must be destructured', ({ todos }) => { 
  expect(todos.length).toBe(2)
})

자동 픽스처 ​

Vitest는 픽스처에 대한 튜플 구문도 지원하며, 각 픽스처에 대한 옵션을 전달할 수 있습니다. 예를 들어, 테스트에서 사용되지 않더라도 픽스처를 명시적으로 초기화하는 데 사용할 수 있습니다.

ts
import { test as base } from 'vitest';

const test = base.extend({
  fixture: [
    async ({}, use) => {
      // 이 함수가 실행됩니다.
      setup();
      await use();
      teardown();
    },
    { auto: true }, // 자동 픽스처로 표시
  ],
});

test('works correctly');

기본 픽스처 ​

Vitest 3부터는 다른 프로젝트에서 다른 값을 제공할 수 있습니다. 이 기능을 활성화하려면 옵션에 { injected: true }를 전달해야 합니다. 프로젝트 구성에 키가 지정되지 않은 경우 기본값이 사용됩니다.

ts
import { test as base } from 'vitest';

const test = base.extend({
  url: [
    // 구성에 "url"이 정의되지 않은 경우 기본값
    '/default',
    // 재정의를 허용하도록 픽스처를 "주입 가능"으로 표시
    { injected: true },
  ],
});

test('works correctly', ({ url }) => {
  // "project-new"에서 url은 "/default"입니다.
  // "project-full"에서 url은 "/full"입니다.
  // "project-empty"에서 url은 "/empty"입니다.
});
ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    projects: [
      {
        test: {
          name: 'project-new',
        },
      },
      {
        test: {
          name: 'project-full',
          provide: {
            url: '/full',
          },
        },
      },
      {
        test: {
          name: 'project-empty',
          provide: {
            url: '/empty',
          },
        },
      },
    ],
  },
});

스위트 범위 지정 값 3.1.0+ ​

Vitest 3.1부터 test.scoped API를 사용하여 스위트 및 해당 하위 항목별로 컨텍스트 값을 재정의할 수 있습니다.

ts
import { test as baseTest, describe, expect } from 'vitest';

const test = baseTest.extend({
  dependency: 'default',
  dependant: ({ dependency }, use) => use({ dependency }),
});

describe('use scoped values', () => {
  test.scoped({ dependency: 'new' });

  test('uses scoped value', ({ dependant }) => {
    // `dependant`는 이 스위트의 모든 테스트에 범위가 지정된
    // 새로 재정의된 값을 사용합니다.
    expect(dependant).toEqual({ dependency: 'new' });
  });

  describe('keeps using scoped value', () => {
    test('uses scoped value', ({ dependant }) => {
      // 중첩된 스위트가 값을 상속했습니다.
      expect(dependant).toEqual({ dependency: 'new' });
    });
  });
});

test('keep using the default values', ({ dependant }) => {
  // `dependency`는 .scoped가 있는 스위트 외부에서
  // 기본값을 사용합니다.
  expect(dependant).toEqual({ dependency: 'default' });
});

이 API는 데이터베이스 연결과 같은 동적 변수에 의존하는 컨텍스트 값이 있는 경우 특히 유용합니다.

ts
const test = baseTest.extend<{
  db: Database;
  schema: string;
}>({
  db: async ({ schema }, use) => {
    const db = await createDb({ schema });
    await use(db);
    await cleanup(db);
  },
  schema: '',
});

describe('one type of schema', () => {
  test.scoped({ schema: 'schema-1' });

  // ... 테스트
});

describe('another type of schema', () => {
  test.scoped({ schema: 'schema-2' });

  // ... 테스트
});

범위별 컨텍스트 3.2.0+ ​

파일 또는 워커당 한 번 시작되는 컨텍스트를 정의할 수 있습니다. 객체 매개변수를 통해 일반 픽스처와 동일한 방식으로 시작됩니다.

ts
import { test as baseTest } from 'vitest';

export const test = baseTest.extend({
  perFile: [({}, { use }) => use([]), { scope: 'file' }],
  perWorker: [({}, { use }) => use([]), { scope: 'worker' }],
});

값은 픽스처 옵션에 auto: true가 없는 한, 테스트가 처음 접근했을 때 초기화됩니다. 이 경우 값은 어떤 테스트가 실행되기 전에 초기화됩니다.

ts
const test = baseTest.extend({
  perFile: [
    ({}, { use }) => use([]),
    {
      scope: 'file',
      // 어떤 테스트 전에 항상 이 훅을 실행합니다.
      auto: true,
    },
  ],
});

worker 범위는 워커당 한 번 픽스처를 실행합니다. 실행 중인 워커의 수는 다양한 요인에 따라 달라집니다. 기본적으로 모든 파일은 별도의 워커에서 실행되므로 file 및 worker 범위는 동일하게 작동합니다.

그러나 격리를 비활성화하면 워커 수는 maxWorkers 또는 poolOptions 구성에 의해 제한됩니다.

vmThreads 또는 vmForks에서 테스트를 실행할 때 scope: 'worker'를 지정하면 scope: 'file'과 동일하게 작동합니다. 이 제한은 모든 테스트 파일에 자체 VM 컨텍스트가 있기 때문에 Vitest가 한 번만 초기화하면 한 컨텍스트의 내용이 다른 컨텍스트로 유출되어 많은 참조 불일치(예: 동일한 클래스의 인스턴스가 다른 생성자를 참조)를 생성할 수 있기 때문에 존재합니다.

TypeScript ​

모든 사용자 지정 컨텍스트에 대한 픽스처 유형을 제공하려면 픽스처 유형을 제네릭으로 전달할 수 있습니다.

ts
interface MyFixtures {
  todos: number[];
  archive: number[];
}

const test = baseTest.extend<MyFixtures>({
  todos: [],
  archive: [],
});

test('types are defined correctly', ({ todos, archive }) => {
  expectTypeOf(todos).toEqualTypeOf<number[]>();
  expectTypeOf(archive).toEqualTypeOf<number[]>();
});

타입 추론

use 함수가 호출될 때 Vitest는 타입 추론을 지원하지 않습니다. test.extend가 호출될 때 전체 컨텍스트 타입을 제네릭 타입으로 전달하는 것이 좋습니다.

ts
import { test as baseTest } from 'vitest';

const test = baseTest.extend<{
  todos: number[];
  schema: string;
}>({
  todos: ({ schema }, use) => use([]),
  schema: 'test',
});

test('types are correct', ({
  todos, // number[]
  schema, // string
}) => {
  // ...
});

beforeEach 및 afterEach ​

Deprecated

이것은 컨텍스트를 확장하는 구식 방법이며 test가 test.extend로 확장될 때는 작동하지 않습니다.

컨텍스트는 각 테스트마다 다릅니다. beforeEach 및 afterEach 훅 내에서 컨텍스트에 접근하고 확장할 수 있습니다.

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

beforeEach(async context => {
  // 컨텍스트 확장
  context.foo = 'bar';
});

it('should work', ({ foo }) => {
  console.log(foo); // 'bar'
});

TypeScript ​

모든 사용자 지정 컨텍스트에 대한 속성 유형을 제공하려면 TestContext 유형을 다음과 같이 확장할 수 있습니다.

ts
declare module 'vitest' {
  export interface TestContext {
    foo?: string;
  }
}

특정 beforeEach, afterEach, it 및 test 훅에 대해서만 속성 유형을 제공하려면 유형을 제네릭으로 전달할 수 있습니다.

ts
interface LocalTestContext {
  foo: string;
}

beforeEach<LocalTestContext>(async context => {
  // context의 타입은 'TestContext & LocalTestContext'입니다.
  context.foo = 'bar';
});

it<LocalTestContext>('should work', ({ foo }) => {
  // foo의 타입은 'string'입니다.
  console.log(foo); // 'bar'
});
Pager
이전소스 내 테스팅
다음테스트 어노테이션

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

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/guide/test-context

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

Copyright (c) 2021-Present Vitest Team