テストコンテキスト
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);
});
この API は、グローバルな expect
ではスナップショットテストを追跡できないため、スナップショットテストを並行して実行する場合に役立ちます。
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 では、テストコンテキストを拡張するための 2 つの方法が提供されています。
test.extend
WARNING
この API は Vitest 0.32.3 以降で使用可能です。
Playwright と同様に、このメソッドを使用して、カスタムフィクスチャを持つ独自の test
API を定義し、再利用できます。
例えば、todos
と archive
という 2 つのフィクスチャを使って 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);
});
さらにフィクスチャを追加したり、既存のフィクスチャをオーバーライドしたりすることも可能です。
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('', () => {});
myTest('', ({ 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 => {
// typeof context is 'TestContext & LocalTestContext'
context.foo = 'bar';
});
it<LocalTestContext>('should work', ({ foo }) => {
// typeof foo is 'string'
console.log(foo); // 'bar'
});