테스트 컨텍스트
Playwright Fixtures에서 영감을 받은 Vitest의 테스트 컨텍스트를 사용하면 테스트에 필요한 유틸리티, 상태, 픽스처 등을 정의할 수 있습니다.
사용법
각 테스트 콜백 함수의 첫 번째 인자는 테스트 컨텍스트입니다.
import { it } from 'vitest';
it('should work', ctx => {
// 테스트 이름을 출력합니다.
console.log(ctx.task.name);
});
내장 테스트 컨텍스트
context.task
테스트에 대한 메타데이터를 포함하는 읽기 전용 객체입니다.
context.expect
현재 테스트에 바인딩된 expect
API입니다.
import { it } from 'vitest';
it('math is easy', ({ expect }) => {
expect(2 + 2).toBe(4);
});
전역 expect
는 스냅샷 테스트를 추적할 수 없으므로, 이 API는 스냅샷 테스트를 동시에 실행할 때 유용합니다.
import { it } from 'vitest';
it.concurrent('math is easy', ({ expect }) => {
expect(2 + 2).toMatchInlineSnapshot();
});
it.concurrent('math is hard', ({ expect }) => {
expect(2 * 2).toMatchInlineSnapshot();
});
context.skip
후속 테스트 실행을 건너뛰고 테스트를 건너뛴 것으로 표시합니다.
import { expect, it } from 'vitest';
it('math is hard', ({ skip }) => {
skip();
expect(2 + 2).toBe(5);
});
테스트 컨텍스트 확장
Vitest는 테스트 컨텍스트를 확장할 수 있는 두 가지 방법을 제공합니다.
test.extend
WARNING
이 API는 Vitest 0.32.3부터 사용할 수 있습니다.
Playwright와 마찬가지로 이 메서드를 사용하여 사용자 정의 픽스처로 자신만의 test
API를 정의하고 재사용할 수 있습니다.
예를 들어 먼저 두 개의 픽스처인 todos
와 archive
로 myTest
를 만듭니다.
// my-test.ts
import { test } from 'vitest';
const todos = [];
const archive = [];
export const myTest = test.extend({
todos: async ({ task }, use) => {
// 각 테스트 함수 전에 픽스처 설정
todos.push(1, 2, 3);
// 픽스처 값 사용
await use(todos);
// 각 테스트 함수 후에 픽스처 정리
todos.length = 0;
},
archive,
});
그런 다음 가져와서 사용할 수 있습니다.
import { expect } from 'vitest';
import { myTest } from './my-test.ts';
myTest('add items to todos', ({ todos }) => {
expect(todos.length).toBe(3);
todos.add(4);
expect(todos.length).toBe(4);
});
myTest('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);
});
myTest
를 확장하여 더 많은 픽스처를 추가하거나 기존 픽스처를 재정의할 수도 있습니다.
export const myTest2 = myTest.extend({
settings: {
// ...
},
});
픽스처 초기화
Vitest 러너는 픽스처 사용 여부에 따라 자동으로 초기화하고 테스트 컨텍스트에 주입합니다.
import { test } from 'vitest';
async function todosFn({ task }, use) {
await use([1, 2, 3]);
}
const myTest = test.extend({
todos: todosFn,
archive: [],
});
// todosFn은 실행되지 않습니다.
myTest('', () => {});
myTets('', ({ archive }) => {});
// todosFn은 실행됩니다.
myTest('', ({ todos }) => {});
WARNING
픽스처와 함께 test.extend()
를 사용하는 경우 픽스처 함수와 테스트 함수 모두에서 컨텍스트에 액세스하려면 항상 객체 구조 분해 할당 패턴 { todos }
를 사용해야 합니다.
TypeScript
사용자 정의 컨텍스트 전체에 픽스처 타입을 적용하려면, 픽스처 타입을 제네릭으로 전달하면 됩니다.
interface MyFixtures {
todos: number[];
archive: number[];
}
const myTest = test.extend<MyFixtures>({
todos: [],
archive: [],
});
myTest('', context => {
expectTypeOf(context.todos).toEqualTypeOf<number[]>();
expectTypeOf(context.archive).toEqualTypeOf<number[]>();
});
beforeEach
및 afterEach
컨텍스트는 각 테스트마다 독립적입니다. beforeEach
및 afterEach
훅 내에서 컨텍스트에 액세스하고 확장할 수 있습니다.
import { beforeEach, it } from 'vitest';
beforeEach(async context => {
// 컨텍스트 확장
context.foo = 'bar';
});
it('should work', ({ foo }) => {
console.log(foo); // 'bar'
});
TypeScript
사용자 정의 컨텍스트 전체에 속성 타입을 적용하려면, 아래와 같이 TestContext
타입에 속성을 추가하여 확장할 수 있습니다.
declare module 'vitest' {
export interface TestContext {
foo?: string;
}
}
특정 beforeEach
, afterEach
, it
및 test
훅에 대해서만 속성 타입을 제공하려면 타입을 제네릭으로 전달할 수 있습니다.
interface LocalTestContext {
foo: string;
}
beforeEach<LocalTestContext>(async context => {
// context의 타입은 'TestContext & LocalTestContext'입니다.
context.foo = 'bar';
});
it<LocalTestContext>('should work', ({ foo }) => {
// typeof foo is 'string'
console.log(foo); // 'bar'
});