테스트 API 참조
다음 타입은 아래 타입 서명에 사용됩니다.
type Awaitable<T> = T | PromiseLike<T>;
type TestFunction = () => Awaitable<void>;
interface TestOptions {
/**
* 실행 시간이 초과되면 테스트가 실패합니다.
*/
timeout?: number;
/**
* 실패 시 지정된 횟수만큼 테스트를 재시도합니다.
*
* @default 0
*/
retry?: number;
/**
* 매번 실패하더라도 동일한 테스트를 여러 번 반복합니다.
* "retry" 옵션이 활성화되어 있고 테스트가 실패하면, 각 반복 주기마다 모든 재시도를 수행합니다.
* 임의적인 실패를 디버깅하는 데 유용합니다.
*
* @default 0
*/
repeats?: number;
}Vitest 1.3.0에서는 옵션을 마지막 매개변수로 사용하는 것이 더 이상 사용되지 않습니다. 이 구문은 2.0.0 버전에서 제거될 때까지 더 이상 사용되지 않는다는 메시지가 표시됩니다. 옵션을 전달해야 하는 경우 test 함수의 두 번째 인수를 사용하십시오.
import { test } from 'vitest';
test('flaky test', () => {}, { retry: 3 });
test('flaky test', { retry: 3 }, () => {}); 테스트 함수가 Promise를 반환하면, 테스트 실행기는 비동기 검증을 위해 Promise가 완료될 때까지 기다립니다. Promise가 거부되면 테스트는 실패합니다.
TIP
Jest에서 TestFunction은 (done: DoneCallback) => void 타입일 수도 있습니다. 이 형식이 사용되면 done이 호출될 때까지 테스트가 완료되지 않습니다. async 함수를 사용하여 동일한 결과를 얻을 수 있습니다. 마이그레이션 가이드 Done Callback 섹션을 참조하세요.
Vitest 1.3.0부터 대부분의 옵션이 점(dot) 구문과 객체 구문을 모두 지원하므로 원하는 스타일을 사용할 수 있습니다.
import { test } from 'vitest';
test.skip('skipped test', () => {
// some logic that fails right now
});import { test } from 'vitest';
test('skipped test', { skip: true }, () => {
// some logic that fails right now
});test
- 별칭:
it
test는 관련된 테스트들의 집합을 정의합니다. 테스트 이름과 테스트할 검증 로직을 담고 있는 함수를 인자로 받습니다.
선택적으로, 테스트 종료 전에 대기할 시간(밀리초)을 지정하는 타임아웃을 설정할 수 있습니다. 기본값은 5초이며, testTimeout 설정을 통해 전역적으로 구성할 수 있습니다.
import { expect, test } from 'vitest';
test('should work as expected', () => {
expect(Math.sqrt(4)).toBe(2);
});test.extend 0.32.3+
- 별칭:
it.extend
test.extend를 사용하여 사용자 정의 픽스처로 테스트 컨텍스트를 확장합니다. 이 함수는 새로운 test 함수를 반환하며, 반환된 test 함수 또한 확장 가능하므로 필요에 따라 픽스처를 추가하거나 기존 픽스처를 재정의할 수 있습니다. 자세한 내용은 테스트 컨텍스트 확장을 참조하세요.
import { expect, test } from 'vitest';
const todos = [];
const archive = [];
const myTest = test.extend({
todos: async ({ task }, use) => {
todos.push(1, 2, 3);
await use(todos);
todos.length = 0;
},
archive,
});
myTest('add item', ({ todos }) => {
expect(todos.length).toBe(3);
todos.push(4);
expect(todos.length).toBe(4);
});test.skip
- 별칭:
it.skip
특정 테스트를 실행하지 않으려면, 코드를 삭제하지 않고 실행을 건너뛰고 싶을 때 test.skip을 사용합니다.
import { assert, test } from 'vitest';
test.skip('skipped test', () => {
// Test skipped, no error
assert.equal(Math.sqrt(4), 3);
});테스트 컨텍스트 내에서 skip을 동적으로 호출하여 테스트를 건너뛸 수도 있습니다.
import { assert, test } from 'vitest';
test('skipped test', context => {
context.skip();
// Test skipped, no error
assert.equal(Math.sqrt(4), 3);
});test.skipIf
- 별칭:
it.skipIf
때로는 서로 다른 환경에서 테스트를 여러 번 실행해야 할 수 있으며, 일부 테스트는 특정 환경에 따라 달라질 수 있습니다. 테스트 코드를 if 문으로 감싸는 대신, 조건이 참일 경우 test.skipIf를 사용하여 테스트를 건너뛸 수 있습니다.
import { assert, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
test.skipIf(isDev)('prod only test', () => {
// this test only runs in production
});WARNING
Vitest를 타입 검사기로 사용하는 경우 이 구문을 사용할 수 없습니다.
test.runIf
- 별칭:
it.runIf
test.skipIf의 반대 기능을 제공합니다.
import { assert, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
test.runIf(isDev)('dev only test', () => {
// this test only runs in development
});WARNING
Vitest를 타입 검사기로 사용하는 경우 이 구문을 사용할 수 없습니다.
test.only
- 별칭:
it.only
test.only를 사용하여 특정 테스트 묶음 내에서 지정된 테스트만 실행합니다. 이는 디버깅 시 유용합니다.
선택적으로, 테스트 종료 전에 대기할 시간(밀리초)을 지정하는 타임아웃을 설정할 수 있습니다. 기본값은 5초이며, testTimeout 설정을 통해 전역적으로 구성할 수 있습니다.
import { assert, test } from 'vitest';
test.only('test', () => {
// Only this test (and others marked with only) are run
assert.equal(Math.sqrt(4), 2);
});전체 테스트 스위트에서 다른 테스트를 모두 제외하고 특정 파일 내의 only 테스트만 실행하는 것이 유용한 경우가 있습니다.
이를 위해 해당 테스트가 포함된 특정 파일로 vitest를 실행합니다.
# vitest interesting.test.tstest.concurrent
- 별칭:
it.concurrent
test.concurrent는 연속적인 테스트를 병렬로 실행하도록 지정합니다. 테스트 이름, 테스트 로직을 포함하는 비동기 함수, 선택적인 타임아웃(밀리초)을 인자로 받습니다.
import { describe, test } from 'vitest';
// The two tests marked with concurrent will be run in parallel
describe('suite', () => {
test('serial test', async () => {
/* ... */
});
test.concurrent('concurrent test 1', async () => {
/* ... */
});
test.concurrent('concurrent test 2', async () => {
/* ... */
});
});test.skip, test.only 및 test.todo는 동시 테스트와 함께 사용할 수 있습니다. 다음의 모든 조합이 유효합니다.
test.concurrent(/* ... */);
test.skip.concurrent(/* ... */); // or test.concurrent.skip(/* ... */)
test.only.concurrent(/* ... */); // or test.concurrent.only(/* ... */)
test.todo.concurrent(/* ... */); // or test.concurrent.todo(/* ... */)동시 테스트를 실행할 때 스냅샷 및 단언은 올바른 테스트가 감지되도록 로컬 테스트 컨텍스트의 expect를 사용해야 합니다.
test.concurrent('test 1', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
test.concurrent('test 2', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});WARNING
Vitest를 타입 검사기로 사용하는 경우 이 구문을 사용할 수 없습니다.
test.sequential
- 별칭:
it.sequential
test.sequential은 테스트를 순차적으로 실행하도록 표시합니다. 이는 describe.concurrent 내에서 또는 --sequence.concurrent 명령 옵션을 사용하여 테스트를 순서대로 실행하려는 경우에 유용합니다.
import { describe, test } from 'vitest';
// ---cut---
// 구성 옵션 { sequence: { concurrent: true } } 사용 시
test('concurrent test 1', async () => {
/* ... */
});
test('concurrent test 2', async () => {
/* ... */
});
test.sequential('sequential test 1', async () => {
/* ... */
});
test.sequential('sequential test 2', async () => {
/* ... */
});
// 동시 스위트 내에서
describe.concurrent('suite', () => {
test('concurrent test 1', async () => {
/* ... */
});
test('concurrent test 2', async () => {
/* ... */
});
test.sequential('sequential test 1', async () => {
/* ... */
});
test.sequential('sequential test 2', async () => {
/* ... */
});
});test.todo
- 별칭:
it.todo
test.todo를 사용하여 나중에 구현될 테스트를 위한 스텁(stub)을 생성합니다. 보고서에 해당 테스트 항목이 표시되므로 아직 구현해야 할 테스트 수를 파악할 수 있습니다.
// An entry will be shown in the report for this test
test.todo('unimplemented test');test.fails
- 별칭:
it.fails
test.fails는 테스트가 실패할 것으로 예상됨을 명시적으로 나타냅니다.
import { expect, test } from 'vitest';
function myAsyncFunc() {
return new Promise(resolve => resolve(1));
}
test.fails('fail test', async () => {
await expect(myAsyncFunc()).rejects.toBe(1);
});WARNING
Vitest를 타입 검사기로 사용하는 경우 이 구문을 사용할 수 없습니다.
test.each
- 별칭:
it.each
여러 데이터 세트로 동일한 테스트를 반복 실행해야 하는 경우 test.each를 사용합니다. 테스트 함수 매개변수 순서대로 테스트 이름에 printf 포맷을 사용하여 매개변수를 삽입할 수 있습니다.
%s: 문자열%d: 숫자%i: 정수%f: 부동 소수점 값%j: json%o: 객체%#: 테스트 케이스의 인덱스%%: 단일 퍼센트 기호('%')
import { expect, test } from 'vitest';
// ---cut---
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => {
expect(a + b).toBe(expected);
});
// this will return
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3객체를 인수로 사용하는 경우 $ 접두사를 사용하여 객체 속성에 접근할 수도 있습니다.
test.each([
{ a: 1, b: 1, expected: 2 },
{ a: 1, b: 2, expected: 3 },
{ a: 2, b: 1, expected: 3 },
])('add($a, $b) -> $expected', ({ a, b, expected }) => {
expect(a + b).toBe(expected);
});
// this will return
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3객체를 인수로 사용하는 경우 .을 사용하여 객체 속성에 접근할 수도 있습니다.
test.each`
a | b | expected
${{ val: 1 }} | ${'b'} | ${'1b'}
${{ val: 2 }} | ${'b'} | ${'2b'}
${{ val: 3 }} | ${'b'} | ${'3b'}
`('add($a.val, $b) -> $expected', ({ a, b, expected }) => {
expect(a.val + b).toBe(expected);
});
// this will return
// ✓ add(1, b) -> 1b
// ✓ add(2, b) -> 2b
// ✓ add(3, b) -> 3bVitest 0.25.3부터 템플릿 리터럴 테이블을 사용할 수도 있습니다.
- 첫 번째 행은
|로 구분된 열 이름이어야 합니다. - 하나 이상의 후속 데이터 행은
${value}구문을 사용하여 템플릿 리터럴 표현식으로 제공됩니다.
import { expect, test } from 'vitest';
// ---cut---
test.each`
a | b | expected
${1} | ${1} | ${2}
${'a'} | ${'b'} | ${'ab'}
${[]} | ${'b'} | ${'b'}
${{}} | ${'b'} | ${'[object Object]b'}
${{ asd: 1 }} | ${'b'} | ${'[object Object]b'}
`('returns $expected when $a is added $b', ({ a, b, expected }) => {
expect(a + b).toBe(expected);
});TestContext에 액세스하려면 단일 테스트와 함께 describe.each를 사용하십시오.
TIP
Vitest는 chai format 메서드로 $values를 처리합니다. 값이 너무 잘리면 구성 파일에서 chaiConfig.truncateThreshold 값을 늘릴 수 있습니다.
WARNING
Vitest를 타입 검사기로 사용하는 경우 이 구문을 사용할 수 없습니다.
bench
- 타입:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
bench는 성능 측정을 정의합니다. Vitest에서 벤치마크는 일련의 작업을 정의하는 함수를 의미합니다. Vitest는 이 함수를 여러 번 실행하여 다양한 성능 결과를 보여줍니다.
Vitest는 내부적으로 tinybench 라이브러리를 사용하며, 세 번째 인수로 사용할 수 있는 모든 옵션을 상속합니다.
import { bench } from 'vitest';
bench(
'normal sorting',
() => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
},
{ time: 1000 }
);export interface Options {
/**
* 벤치마크 작업을 실행하는 데 필요한 시간(밀리초)
* @default 500
*/
time?: number;
/**
* 시간 옵션이 완료된 경우에도 작업이 실행되어야 하는 횟수
* @default 10
*/
iterations?: number;
/**
* 밀리초 단위로 현재 타임스탬프를 가져오는 함수
*/
now?: () => number;
/**
* 벤치마크를 중단하기 위한 AbortSignal
*/
signal?: AbortSignal;
/**
* 준비 시간 (warm-up time, 밀리초)
* @default 100ms
*/
warmupTime?: number;
/**
* 준비 반복 횟수
* @default 5
*/
warmupIterations?: number;
/**
* 각 벤치마크 작업(주기) 전에 실행할 설정 함수
*/
setup?: Hook;
/**
* 각 벤치마크 작업(주기) 후에 실행할 정리 함수
*/
teardown?: Hook;
}bench.skip
- 타입:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
bench.skip 구문을 사용하여 특정 벤치마크의 실행을 건너뛸 수 있습니다.
import { bench } from 'vitest';
bench.skip('normal sorting', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});bench.only
- 타입:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
bench.only를 사용하여 주어진 테스트 묶음에서 특정 벤치마크만 실행합니다. 이는 디버깅 시 유용합니다.
import { bench } from 'vitest';
bench.only('normal sorting', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});bench.todo
- 타입:
(name: string | Function) => void
bench.todo는 나중에 구현할 벤치마크를 위한 자리 표시자(stub) 역할을 합니다.
import { bench } from 'vitest';
bench.todo('unimplemented test');describe
파일 최상위 레벨에서 test 또는 bench를 사용하면 해당 파일이 암묵적인 테스트 스위트의 일부로 간주됩니다. describe를 사용하면 현재 컨텍스트에서 관련된 테스트, 벤치마크 및 다른 중첩된 스위트들을 묶어 새로운 테스트 그룹을 정의할 수 있습니다. 테스트 그룹을 사용하면 테스트 및 벤치마크를 체계적으로 구성하여 보고서를 더 명확하게 만들 수 있습니다.
// basic.spec.ts
// 테스트 구성
import { describe, expect, test } from 'vitest';
const person = {
isActive: true,
age: 32,
};
describe('person', () => {
test('person is defined', () => {
expect(person).toBeDefined();
});
test('is active', () => {
expect(person.isActive).toBeTruthy();
});
test('age limit', () => {
expect(person.age).toBeLessThanOrEqual(32);
});
});// basic.bench.ts
// 벤치마크 구성
import { bench, describe } from 'vitest';
describe('sort', () => {
bench('normal', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});
bench('reverse', () => {
const x = [1, 5, 4, 2, 3];
x.reverse().sort((a, b) => {
return a - b;
});
});
});테스트 또는 벤치마크 계층 구조를 만들고 싶다면 describe 구문을 중첩하여 사용할 수 있습니다.
import { describe, expect, test } from 'vitest';
function numberToCurrency(value: number | string) {
if (typeof value !== 'number') throw new Error('Value must be a number');
return value
.toFixed(2)
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
describe('numberToCurrency', () => {
describe('given an invalid number', () => {
test('composed of non-numbers to throw error', () => {
expect(() => numberToCurrency('abc')).toThrowError();
});
});
describe('given a valid number', () => {
test('returns the correct currency format', () => {
expect(numberToCurrency(10000)).toBe('10,000.00');
});
});
});describe.skip
- Alias:
suite.skip
특정 describe 구문의 실행을 건너뛰려면 해당 스위트 내에서 describe.skip을 사용합니다.
import { assert, describe, test } from 'vitest';
describe.skip('skipped suite', () => {
test('sqrt', () => {
// 스위트가 생략되었으므로 오류가 발생하지 않습니다.
assert.equal(Math.sqrt(4), 3);
});
});describe.skipIf
- Alias:
suite.skipIf
때로는 여러 환경에서 스위트를 반복적으로 실행해야 할 수 있으며, 일부 스위트는 특정 환경에 따라 달라질 수 있습니다. if 문으로 스위트를 감싸는 대신, 조건이 참일 경우 describe.skipIf를 사용하여 스위트 실행을 건너뛸 수 있습니다.
import { describe, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
describe.skipIf(isDev)('prod only test', () => {
// 이 테스트는 프로덕션 환경에서만 실행됩니다.
});WARNING
Vitest를 타입 검사기로 사용하는 경우 이 구문을 사용할 수 없습니다.
describe.runIf
- 별칭:
suite.runIf
describe.skipIf의 반대입니다.
import { assert, describe, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
describe.runIf(isDev)('dev only test suite', () => {
// this test suite only runs in development
});WARNING
Vitest를 타입 검사기로 사용하는 경우 이 구문을 사용할 수 없습니다.
describe.only
- 타입:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void
특정 스위트만 실행하려면 describe.only를 사용합니다.
import { assert, describe, test } from 'vitest';
// ---cut---
// 이 스위트(및 only로 표시된 다른 스위트)만 실행됩니다.
describe.only('suite', () => {
test('sqrt', () => {
assert.equal(Math.sqrt(4), 3);
});
});
describe('other suite', () => {
// ... 생략됨
});전체 테스트 스위트의 결과를 복잡하게 만드는 다른 테스트를 제외하고 특정 파일 내에서 only로 지정된 테스트만 실행하는 것이 유용한 경우가 있습니다.
이를 위해 해당 테스트가 포함된 특정 파일을 지정하여 vitest를 실행합니다.
# vitest interesting.test.tsdescribe.concurrent
- Alias:
suite.concurrent
스위트 내에서 describe.concurrent를 사용하면 해당 스위트 내의 모든 테스트가 동시에 실행되도록 설정됩니다.
import { describe, test } from 'vitest';
// ---cut---
// 이 스위트 내의 모든 테스트는 병렬로 실행됩니다.
describe.concurrent('suite', () => {
test('concurrent test 1', async () => {
/* ... */
});
test('concurrent test 2', async () => {
/* ... */
});
test.concurrent('concurrent test 3', async () => {
/* ... */
});
});.skip, .only 및 .todo는 동시 스위트에서도 작동합니다. 다음의 모든 조합이 유효합니다.
describe.concurrent(/* ... */);
describe.skip.concurrent(/* ... */); // 또는 describe.concurrent.skip(/* ... */)
describe.only.concurrent(/* ... */); // 또는 describe.concurrent.only(/* ... */)
describe.todo.concurrent(/* ... */); // 또는 describe.concurrent.todo(/* ... */)동시 테스트를 실행할 때 스냅샷 및 검증은 올바른 테스트가 감지되도록 로컬 테스트 컨텍스트에서 expect를 사용해야 합니다.
describe.concurrent('suite', () => {
test('concurrent test 1', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
test('concurrent test 2', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
});WARNING
Vitest를 타입 검사기로 사용하는 경우 이 구문을 사용할 수 없습니다.
describe.sequential
- Alias:
suite.sequential
스위트에서 describe.sequential은 해당 스위트 내의 모든 테스트를 순차적으로 실행하도록 지정합니다. 이는 describe.concurrent 블록 내에서 또는 --sequence.concurrent 명령 옵션을 사용하여 테스트를 순차적으로 실행하려는 경우에 유용합니다.
import { describe, test } from 'vitest';
// ---cut---
describe.concurrent('suite', () => {
test('concurrent test 1', async () => {
/* ... */
});
test('concurrent test 2', async () => {
/* ... */
});
describe.sequential('', () => {
test('sequential test 1', async () => {
/* ... */
});
test('sequential test 2', async () => {
/* ... */
});
});
});describe.shuffle
- Alias:
suite.shuffle
Vitest는 CLI 플래그 --sequence.shuffle 또는 구성 옵션 sequence.shuffle을 통해 전체 테스트를 임의의 순서로 실행하는 기능을 제공합니다. 하지만 테스트 스위트의 일부만 임의 순서로 실행하고 싶다면 이 플래그를 사용할 수 있습니다.
import { describe, test } from 'vitest';
// ---cut---
describe.shuffle('suite', () => {
test('random test 1', async () => {
/* ... */
});
test('random test 2', async () => {
/* ... */
});
test('random test 3', async () => {
/* ... */
});
});
// 순서는 구성의 sequence.seed 옵션에 따라 달라집니다(기본적으로 Date.now())..skip, .only 및 .todo는 임의 스위트에서도 작동합니다.
WARNING
Vitest를 타입 검사기로 사용하는 경우 이 구문을 사용할 수 없습니다.
describe.todo
- Alias:
suite.todo
나중에 구현할 스위트를 스텁(stub) 처리하려면 describe.todo를 사용합니다. 구현해야 할 테스트의 개수를 보고서에서 확인할 수 있도록 해당 항목이 표시됩니다.
// 이 스위트에 대한 항목이 보고서에 표시됩니다.
describe.todo('unimplemented suite');describe.each
- Alias:
suite.each
동일한 데이터 세트를 기반으로 여러 테스트를 수행해야 하는 경우 describe.each를 사용합니다.
import { describe, expect, test } from 'vitest';
// ---cut---
describe.each([
{ a: 1, b: 1, expected: 2 },
{ a: 1, b: 2, expected: 3 },
{ a: 2, b: 1, expected: 3 },
])('describe object add($a, $b)', ({ a, b, expected }) => {
test(`returns ${expected}`, () => {
expect(a + b).toBe(expected);
});
test(`returned value not be greater than ${expected}`, () => {
expect(a + b).not.toBeGreaterThan(expected);
});
test(`returned value not be less than ${expected}`, () => {
expect(a + b).not.toBeLessThan(expected);
});
});Vitest 0.25.3부터 템플릿 리터럴 테이블을 사용할 수도 있습니다.
- 첫 번째 행은
|로 구분된 열 이름이어야 합니다. ${value}구문을 사용하여 템플릿 리터럴 표현식으로 제공되는 하나 이상의 후속 데이터 행.
import { describe, expect, test } from 'vitest';
// ---cut---
describe.each`
a | b | expected
${1} | ${1} | ${2}
${'a'} | ${'b'} | ${'ab'}
${[]} | ${'b'} | ${'b'}
${{}} | ${'b'} | ${'[object Object]b'}
${{ asd: 1 }} | ${'b'} | ${'[object Object]b'}
`('describe template string add($a, $b)', ({ a, b, expected }) => {
test(`returns ${expected}`, () => {
expect(a + b).toBe(expected);
});
});WARNING
Vitest를 타입 검사기로 사용하는 경우 이 구문을 사용할 수 없습니다.
설정 및 해체
이러한 함수를 사용하면 테스트 생명 주기에 연결하여 설정 및 해체 코드를 반복하는 것을 피할 수 있습니다. 최상위 레벨에서 사용되는 경우 파일에 적용되고, describe 구문 내부에 있는 경우 현재 스위트에 적용됩니다. Vitest를 타입 검사기로 실행하는 경우 이러한 훅은 호출되지 않습니다.
beforeEach
- 타입:
beforeEach(fn: () => Awaitable<void>, timeout?: number)
현재 컨텍스트에서 각 테스트가 실행되기 전에 호출될 콜백 함수를 등록합니다. 함수가 Promise 객체를 반환하면 Vitest는 테스트를 실행하기 전에 Promise 객체가 완료될 때까지 기다립니다.
선택적으로 종료하기 전에 대기할 시간(밀리초)을 정의하는 시간 초과를 전달할 수 있습니다. 기본값은 5초입니다.
import { beforeEach } from 'vitest';
beforeEach(async () => {
// 각 테스트 실행 전에 모의 데이터를 초기화하고 필요한 테스트 데이터를 추가합니다.
await stopMocking();
await addUser({ name: 'John' });
});위 예제에서 beforeEach는 각 테스트마다 사용자를 추가합니다.
Vitest v0.10.0부터 beforeEach는 선택적 정리 함수( afterEach와 동일)도 허용합니다.
import { beforeEach } from 'vitest';
beforeEach(async () => {
// 각 테스트 실행 전에 한 번 호출됩니다.
await prepareSomething();
// 정리 함수, 각 테스트 실행 후에 한 번 호출됩니다.
return async () => {
await resetSomething();
};
});afterEach
- 타입:
afterEach(fn: () => Awaitable<void>, timeout?: number)
현재 컨텍스트에서 각 테스트가 완료된 후 호출될 콜백 함수를 등록합니다. 함수가 Promise 객체를 반환하면 Vitest는 계속하기 전에 Promise 객체가 완료될 때까지 기다립니다.
선택적으로 종료하기 전에 대기할 시간을 지정하기 위해 시간 초과(밀리초)를 제공할 수 있습니다. 기본값은 5초입니다.
import { afterEach } from 'vitest';
afterEach(async () => {
await clearTestingData(); // 각 테스트 실행 후 테스트 데이터 지우기
});위 예제에서 afterEach는 각 테스트 실행 후에 테스트 데이터가 정리되도록 보장합니다.
TIP
Vitest 1.3.0에 onTestFinished 훅이 추가되었습니다. 테스트 실행 중에 이 훅을 호출하여 테스트가 완료된 후 상태를 정리할 수 있습니다.
beforeAll
- 타입:
beforeAll(fn: () => Awaitable<void>, timeout?: number)
현재 컨텍스트에서 모든 테스트 실행을 시작하기 전에 한 번 호출될 콜백 함수를 등록합니다. 함수가 Promise 객체를 반환하면 Vitest는 테스트를 실행하기 전에 Promise 객체가 완료될 때까지 기다립니다.
선택적으로 종료하기 전에 대기할 시간을 지정하기 위해 시간 초과(밀리초)를 제공할 수 있습니다. 기본값은 5초입니다.
import { beforeAll } from 'vitest';
beforeAll(async () => {
await startMocking(); // 모든 테스트 실행 전에 한 번 호출됩니다.
});위 예제에서 beforeAll은 모든 테스트를 실행하기 전에 필요한 모의 데이터가 설정되도록 합니다.
Vitest v0.10.0부터 beforeAll은 선택적 정리 함수( afterAll과 동일)도 허용합니다.
import { beforeAll } from 'vitest';
beforeAll(async () => {
// 모든 테스트 실행 전에 한 번 호출됩니다.
await startMocking();
// 정리 함수, 모든 테스트 실행 후에 한 번 호출됩니다.
return async () => {
await stopMocking();
};
});afterAll
- 타입:
afterAll(fn: () => Awaitable<void>, timeout?: number)
현재 컨텍스트에서 모든 테스트가 실행된 후 한 번 호출될 콜백 함수를 등록합니다. 함수가 Promise 객체를 반환하면 Vitest는 계속하기 전에 Promise 객체가 완료될 때까지 기다립니다.
선택적으로 종료하기 전에 대기할 시간을 지정하기 위해 시간 초과(밀리초)를 제공할 수 있습니다. 기본값은 5초입니다.
import { afterAll } from 'vitest';
afterAll(async () => {
await stopMocking(); // 이 메서드는 모든 테스트가 실행된 후에 호출됩니다.
});위 예제에서 afterAll은 모든 테스트가 완료된 후 stopMocking 메서드가 실행되도록 보장합니다.
테스트 훅
Vitest는 테스트 실행 중에 호출하여 테스트 실행이 완료되었을 때 상태를 정리할 수 있는 몇 가지 훅을 제공합니다.
WARNING
이러한 훅은 테스트 본문 외부에서 호출되면 오류를 발생시킵니다.
onTestFinished 1.3.0+
이 훅은 테스트 실행이 완료된 후 항상 호출됩니다. 테스트 결과에 영향을 줄 수 있으므로 afterEach 훅 다음에 호출됩니다. 현재 테스트 결과가 담긴 TaskResult 객체를 받습니다.
import { onTestFinished, test } from 'vitest';
test('performs a query', () => {
const db = connectDb();
onTestFinished(() => db.close());
db.query('SELECT * FROM users');
});WARNING
테스트를 동시에 실행하는 경우 Vitest는 글로벌 훅에서 동시 테스트를 추적하지 않으므로 항상 테스트 컨텍스트에서 onTestFinished 훅을 사용해야 합니다.
import { test } from 'vitest';
test.concurrent('performs a query', ({ onTestFinished }) => {
const db = connectDb();
onTestFinished(() => db.close());
db.query('SELECT * FROM users');
});이 훅은 재사용 가능한 로직을 만들 때 특히 유용합니다.
// 별도의 파일에 있을 수 있습니다.
function getTestDb() {
const db = connectMockedDb();
onTestFinished(() => db.close());
return db;
}
test('performs a user query', async () => {
const db = getTestDb();
expect(await db.query('SELECT * from users').perform()).toEqual([]);
});
test('performs an organization query', async () => {
const db = getTestDb();
expect(await db.query('SELECT * from organizations').perform()).toEqual([]);
});TIP
이 훅은 항상 역순으로 호출되며 sequence.hooks 옵션의 영향을 받지 않습니다.
onTestFailed
이 훅은 테스트가 실패한 후에만 호출됩니다. 테스트 결과에 영향을 줄 수 있으므로 afterEach 훅 다음에 호출됩니다. 현재 테스트 결과가 담긴 TaskResult 객체를 받습니다. 이 훅은 디버깅에 유용합니다.
import { onTestFailed, test } from 'vitest';
test('performs a query', () => {
const db = connectDb();
onTestFailed(e => {
console.log(e.result.errors);
});
db.query('SELECT * FROM users');
});WARNING
테스트를 동시에 실행하는 경우 Vitest는 글로벌 훅에서 동시 테스트를 추적하지 않으므로 항상 테스트 컨텍스트에서 onTestFailed 훅을 사용해야 합니다.
import { test } from 'vitest';
test.concurrent('performs a query', ({ onTestFailed }) => {
const db = connectDb();
onTestFailed(result => {
console.log(result.errors);
});
db.query('SELECT * FROM users');
});