Skip to content
Vitest 2
Main Navigation 가이드API구성브라우저 모드고급
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

Node API

테스트 러너

작업 메타데이터

리포터 확장하기

커스텀 풀

이 페이지에서

테스트 러너 ​

WARNING

이것은 고급 API입니다. 단순히 테스트를 실행하고 싶다면 이 API가 필요하지 않을 수 있습니다. 주로 라이브러리 작성자가 사용합니다.

구성 파일의 runner 옵션을 사용하여 테스트 러너의 경로를 설정할 수 있습니다. 이 파일은 다음 메서드를 구현하는 클래스를 기본 내보내기로 해야 합니다.

ts
export interface VitestRunner {
  /**
   * 실제로 테스트를 수집하고 실행하기 전에 가장 먼저 호출되는 메서드입니다.
   */
  onBeforeCollect?: (paths: string[]) => unknown;
  /**
   * 테스트 수집 후 "onBeforeRun" 이전에 호출됩니다.
   */
  onCollected?: (files: File[]) => unknown;

  /**
   * 테스트 러너가 다음 테스트 실행을 취소해야 할 경우 호출됩니다.
   * 러너는 이 메서드를 수신하여 호출 시 "onBeforeRunSuite" 및 "onBeforeRunTask"에서 테스트와 스위트를 건너뛴 것으로 표시해야 합니다.
   */
  onCancel?: (reason: CancelReason) => unknown;

  /**
   * 단일 테스트를 실행하기 전에 호출됩니다. 이때 "result"는 아직 없습니다.
   */
  onBeforeRunTest?: (test: TaskPopulated) => unknown;
  /**
   * 실제로 테스트 함수를 실행하기 전에 호출됩니다. 이때 "result"는 이미 "state"와 "startTime"을 포함하고 있습니다.
   */
  onBeforeTryTask?: (
    test: TaskPopulated,
    options: { retry: number; repeats: number }
  ) => unknown;
  /**
   * 결과와 상태가 설정된 후에 호출됩니다.
   */
  onAfterRunTask?: (test: TaskPopulated) => unknown;
  /**
   * 테스트 함수를 실행한 직후에 호출됩니다. 이때 새로운 상태는 아직 없습니다. 테스트 함수에서 예외가 발생하면 호출되지 않습니다.
   */
  onAfterTryTask?: (
    test: TaskPopulated,
    options: { retry: number; repeats: number }
  ) => unknown;

  /**
   * 단일 스위트를 실행하기 전에 호출됩니다. 이때 "result"는 아직 없습니다.
   */
  onBeforeRunSuite?: (suite: Suite) => unknown;
  /**
   * 단일 스위트를 실행한 후에 호출됩니다. 이때 상태와 결과가 존재합니다.
   */
  onAfterRunSuite?: (suite: Suite) => unknown;

  /**
   * 정의되어 있다면 일반적인 Vitest 스위트 분할 및 처리 대신 호출됩니다.
   * "before" 및 "after" 훅은 무시되지 않습니다.
   */
  runSuite?: (suite: Suite) => Promise<void>;
  /**
   * 정의되어 있다면 일반적인 Vitest 처리 대신 호출됩니다. 사용자 정의 테스트 함수가 있는 경우 유용합니다.
   * "before" 및 "after" 훅은 무시되지 않습니다.
   */
  runTask?: (test: TaskPopulated) => Promise<void>;

  /**
   * 작업이 업데이트될 때 호출됩니다. 리포터의 "onTaskUpdate"와 동일하지만 테스트와 동일한 스레드에서 실행됩니다.
   */
  onTaskUpdate?: (task: [string, TaskResult | undefined][]) => Promise<void>;

  /**
   * 수집된 경로의 모든 테스트를 실행하기 전에 호출됩니다.
   */
  onBeforeRunFiles?: (files: File[]) => unknown;
  /**
   * 수집된 경로의 모든 테스트를 실행한 직후에 호출됩니다.
   */
  onAfterRunFiles?: (files: File[]) => unknown;
  /**
   * 테스트에 대한 새로운 컨텍스트가 정의될 때 호출됩니다. 컨텍스트에 사용자 정의 속성을 추가하려는 경우 유용합니다.
   * 러너를 사용하여 사용자 정의 컨텍스트만 정의하려면 대신 "setupFiles"에서 "beforeAll"을 사용하는 것을 고려해 보십시오.
   *
   * 이 메서드는 "test"와 "custom" 핸들러 모두에 대해 호출됩니다.
   *
   * @see https://www.getbook.com/en/book/vitest-2/advanced/runner#your-task-function
   */
  extendTaskContext?: <T extends Test | Custom>(
    context: TaskContext<T>
  ) => TaskContext<T>;
  /**
   * 특정 파일이 가져올 때 호출됩니다. 테스트를 수집할 때와 설정 파일을 가져올 때 두 가지 상황에서 호출될 수 있습니다.
   */
  importFile: (filepath: string, source: VitestRunnerImportSource) => unknown;
  /**
   * 공개적으로 사용 가능한 구성입니다.
   */
  config: VitestRunnerConfig;
}

이 클래스를 초기화할 때 Vitest는 Vitest 구성을 전달하며, 이를 config 속성으로 노출해야 합니다.

WARNING

Vitest는 또한 ViteNodeRunner 인스턴스를 __vitest_executor 속성으로 주입합니다. importFile 메서드에서 파일을 처리하는 데 사용할 수 있습니다 (이는 TestRunner 및 BenchmarkRunner의 기본 동작입니다).

ViteNodeRunner는 executeId 메서드를 노출하며, 이는 Vite 친화적인 환경에서 테스트 파일을 가져오는 데 사용됩니다. 즉, Node가 이해할 수 있도록 런타임에 가져오기를 해결하고 파일 내용을 변환합니다.

TIP

스냅샷 지원 및 기타 일부 기능은 러너에 따라 다릅니다. 이 기능을 유지하고 싶다면 vitest/runners에서 가져온 VitestTestRunner에서 러너를 확장할 수 있습니다. 벤치마크 기능을 확장하고 싶다면 BenchmarkNodeRunner도 사용할 수 있습니다.

작업 ​

스위트와 테스트는 내부적으로 tasks라고 불립니다. Vitest 러너는 테스트를 수집하기 전에 File 작업을 초기화합니다. 이는 몇 가지 추가 속성이 있는 Suite의 상위 집합입니다. 모든 작업( File 포함)에서 file 속성으로 접근할 수 있습니다.

ts
interface File extends Suite {
  /**
   * 파일이 속한 풀의 이름입니다.
   * @default 'forks'
   */
  pool?: string;
  /**
   * UNIX 스타일의 파일 경로입니다.
   */
  filepath: string;
  /**
   * 파일이 속한 워크스페이스 프로젝트의 이름입니다.
   */
  projectName: string | undefined;
  /**
   * 파일의 모든 테스트를 수집하는 데 걸린 시간입니다.
   * 이 시간은 파일의 모든 종속 모듈을 임포트하는 시간도 포함합니다.
   */
  collectDuration?: number;
  /**
   * 설정 파일을 가져오는 데 걸린 시간입니다.
   */
  setupDuration?: number;
  /**
   * 테스트 실행 없이 파일이 초기화되었는지 여부입니다.
   * 이는 Vitest에 의해 서버 측에서 상태를 채우기 위해 수행됩니다.
   */
  local?: boolean;
}

모든 스위트에는 수집 단계 중에 채워지는 tasks 속성이 있습니다. 작업 트리를 위에서 아래로 탐색하는 데 유용합니다.

ts
interface Suite extends TaskBase {
  type: 'suite';
  /**
   * 파일 작업입니다. 파일의 루트 작업입니다.
   */
  file: File;
  /**
   * 스위트의 일부인 작업 배열입니다.
   */
  tasks: Task[];
}

모든 작업에는 작업이 위치한 스위트를 참조하는 suite 속성이 있습니다. test 또는 describe가 최상위 수준에서 시작되면 suite 속성이 없습니다 (file과 같지 않습니다!). File도 suite 속성을 갖지 않습니다. 작업을 아래에서 위로 탐색하는 데 유용합니다.

ts
interface Test<ExtraContext = object> extends TaskBase {
  type: 'test';
  /**
   * 테스트 함수에 전달될 테스트 컨텍스트입니다.
   */
  context: TaskContext<Test> & ExtraContext & TestContext;
  /**
   * 파일 작업입니다. 파일의 루트 작업입니다.
   */
  file: File;
  /**
   * `t.skip()` 호출로 인해 작업이 건너뛰어졌는지 여부입니다.
   */
  pending?: boolean;
  /**
   * 작업이 실패하더라도 성공해야 하는지 여부입니다. 작업이 실패하면 통과로 표시됩니다.
   */
  fails?: boolean;
  /**
   * 작업이 실패하면 실행될 훅입니다. 순서는 `sequence.hooks` 옵션에 따라 다릅니다.
   */
  onFailed?: OnTestFailedHandler[];
  /**
   * 작업이 완료된 후 실행될 훅입니다. 순서는 `sequence.hooks` 옵션에 따라 다릅니다.
   */
  onFinished?: OnTestFinishedHandler[];
  /**
   * 테스트 완료 전에 기다려야 할 비동기 기대(async expects)의 Promise를 저장합니다.
   */
  promises?: Promise<any>[];
}

모든 작업에는 result 필드가 있을 수 있습니다. 스위트는 스위트 콜백 또는 beforeAll/afterAll 콜백 내에서 발생한 오류로 인해 테스트를 수집할 수 없는 경우에만 이 필드를 가질 수 있습니다. 테스트는 콜백이 호출된 후 항상 이 필드를 가집니다. 결과에 따라 state 및 errors 필드가 존재합니다. beforeEach 또는 afterEach 콜백에서 오류가 발생하면 발생한 오류가 task.result.errors에 존재합니다.

ts
export interface TaskResult {
  /**
   * 작업의 상태입니다. 수집 중에 `task.mode`를 상속합니다.
   * 작업이 완료되면 `pass` 또는 `fail`로 변경됩니다.
   * - **pass**: 작업이 성공적으로 실행되었습니다.
   * - **fail**: 작업이 실패했습니다.
   */
  state: TaskState;
  /**
   * 작업 실행 중에 발생한 오류입니다.
   * `expect.soft()`가 여러 번 실패한 경우 여러 오류가 발생할 수 있습니다.
   */
  errors?: ErrorWithDiff[];
  /**
   * 작업 실행에 걸린 시간(밀리초)입니다.
   */
  duration?: number;
  /**
   * 작업 실행이 시작된 시간(밀리초)입니다.
   */
  startTime?: number;
  /**
   * 작업 완료 후 힙 크기(바이트)입니다.
   * `logHeapUsage` 옵션이 설정되고 `process.memoryUsage`가 정의된 경우에만 사용할 수 있습니다.
   */
  heap?: number;
  /**
   * 이 작업과 관련된 훅의 상태입니다. 보고 중에 유용합니다.
   */
  hooks?: Partial<
    Record<'afterAll' | 'beforeAll' | 'beforeEach' | 'afterEach', TaskState>
  >;
  /**
   * 작업이 재시도된 횟수입니다. 작업은 실패하고 `retry` 옵션이 설정된 경우에만 재시도됩니다.
   */
  retryCount?: number;
  /**
   * 작업이 반복된 횟수입니다. 작업은 `repeats` 옵션이 설정된 경우에만 반복됩니다. 이 숫자에는 `retryCount`도 포함됩니다.
   */
  repeatCount?: number;
}

사용자 정의 작업 함수 ​

Vitest는 사용자가 내장 리포터를 재사용할 수 있도록 Custom 작업 유형을 노출합니다. 사실상 Test와 동일하지만 유형이 'custom'입니다.

작업은 스위트의 일부인 객체입니다. suite.task 메서드를 사용하여 현재 스위트에 자동으로 추가됩니다.

js
// ./utils/custom.js
import { createTaskCollector, getCurrentSuite, setFn } from 'vitest/suite';

export { afterAll, beforeAll, describe } from 'vitest';

// 이 함수는 수집 단계 중에 호출됩니다.
// 여기서 함수 핸들러를 호출하지 말고,
// "getCurrentSuite().task()" 메서드를 사용하여 스위트 작업에 추가하십시오.
// 참고: createTaskCollector는 "todo"/"each"/...에 대한 지원을 제공합니다.
export const myCustomTask = createTaskCollector(function (name, fn, timeout) {
  getCurrentSuite().task(name, {
    ...this, // "todo"/"skip"/...가 올바르게 추적되도록 합니다.
    meta: {
      customPropertyToDifferentiateTask: true,
    },
    handler: fn,
    timeout,
  });
});
js
// ./garden/tasks.test.js
import { afterAll, beforeAll, describe, myCustomTask } from '../custom.js';
import { gardener } from './gardener.js';

describe('정원 관리', () => {
  beforeAll(() => {
    gardener.putWorkingClothes();
  });

  myCustomTask('잔디 제거', () => {
    gardener.weedTheGrass();
  });
  myCustomTask.todo('잔디 깎기', () => {
    gardener.mowerTheLawn();
  });
  myCustomTask('꽃에 물 주기', () => {
    gardener.waterFlowers();
  });

  afterAll(() => {
    gardener.goHome();
  });
});
bash
vitest ./garden/tasks.test.js

WARNING

사용자 정의 러너가 없거나 runTest 메서드를 정의하지 않은 경우 Vitest는 작업을 자동으로 검색하려고 시도합니다. setFn으로 함수를 추가하지 않으면 실패합니다.

Pager
이전Node API
다음작업 메타데이터

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

Copyright (c) 2024 Mithril Contributors

https://v2.vitest.dev/advanced/runner

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

Copyright (c) 2024 Mithril Contributors