テスト API リファレンス
以下の型は、下記の型シグネチャで使用されます。
type Awaitable<T> = T | PromiseLike<T>;
type TestFunction = () => Awaitable<void>;
interface TestOptions {
/**
* 実行時間が長すぎる場合にテストを失敗させます。
*/
timeout?: number;
/**
* テストが失敗した場合に、指定された回数だけテストを再試行します。
*
* @default 0
*/
retry?: number;
/**
* 毎回失敗した場合でも、同じテストを複数回繰り返します。
* "retry" オプションが設定されている場合、失敗時には各サイクルで設定された再試行回数だけ再試行します。
* ランダムな失敗をデバッグするのに役立ちます。
*
* @default 0
*/
repeats?: number;
}テスト関数が Promise を返す場合、ランナーは非同期処理の結果を収集するために、Promise が解決されるまで待機します。Promise が拒否された場合、テストは失敗します。
TIP
Jest では、TestFunction は (done: DoneCallback) => void 型にもなり得ます。この形式を使用する場合、done が呼び出されるまでテストは完了しません。async 関数を使用しても同じことができます。移行ガイドの Done Callback セクションを参照してください。
ほとんどのオプションは、ドット構文とオブジェクト構文の両方をサポートしており、どちらのスタイルでも使用できます。
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
- エイリアス:
it.extend
test.extend を使用して、カスタムフィクスチャでテストコンテキストを拡張します。これにより、新しい 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', () => {
// このテストは 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', () => {
// このテストは development 環境でのみ実行されます
});WARNING
Vitest を 型チェッカーとして使用している場合、この構文は使用できません。
test.only
- エイリアス:
it.only
test.only を使用して、特定のスイートで特定のテストのみを実行します。これはデバッグに役立ちます。
オプションで、タイムアウトまでの待機時間をミリ秒単位で指定できます。デフォルトは 5 秒で、testTimeout でグローバルに設定できます。
import { assert, test } from 'vitest';
test.only('test', () => {
// このテスト(および only が付いた他のテスト)のみが実行されます
assert.equal(Math.sqrt(4), 2);
});出力が煩雑になるため、テストスイート全体から他のすべてのテストを無視して、特定のファイル内の only テストを実行すると非常に便利な場合があります。
これを行うには、対象のテストを含む特定のファイルで vitest を実行します。
# vitest interesting.test.tstest.concurrent
- エイリアス:
it.concurrent
test.concurrent は、複数のテストを並行して実行するようにマークします。テスト名、テストを含む非同期関数、およびオプションのタイムアウト(ミリ秒単位)を受け取ります。
import { describe, test } from 'vitest';
// concurrent が付いた 2 つのテストは並行して実行されます
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(/* ... */); // または test.concurrent.skip(/* ... */)
test.only.concurrent(/* ... */); // または test.concurrent.only(/* ... */)
test.todo.concurrent(/* ... */); // または 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';
// 構成オプション { 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 を使用して、後で実装されるテストのスタブを作成します。テストのレポートに項目が表示されるため、実装する必要があるテストの数がわかります。
// このテストのエントリがレポートに表示されます
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
TIP
test.each は Jest 互換性のために提供されていますが、 Vitest には、TestContext を統合する追加機能を持つ test.for もあります。
異なる変数で同じテストを実行する必要がある場合は、test.each を使用します。 テスト関数パラメータの順序で、テスト名に printf 形式の書式でパラメータを挿入できます。
%s: string%d: number%i: integer%f: floating point value%j: json%o: object%#: テストケースのインデックス%%: 単一のパーセント記号 ('%')
import { expect, test } from 'vitest';
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => {
expect(a + b).toBe(expected);
});
// 以下のように出力されます
// ✓ 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);
});
// 以下のように出力されます
// ✓ 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 以降では、テンプレートリテラルの表形式も使用できます。
- 最初の行は、
|で区切られた列名である必要があります。 - 1 つ以上の後続のデータ行は、
${value}構文を使用してテンプレートリテラル式として提供されます。
import { expect, test } from 'vitest';
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);
});TIP
Vitest は、chai format メソッドで $values を処理します。値が過度に切り捨てられる場合は、構成ファイルで chaiConfig.truncateThreshold を増やすことができます。
WARNING
Vitest を 型チェッカーとして使用している場合、この構文は使用できません。
test.for
- エイリアス:
it.for
TestContext を提供するための test.each の代替です。
test.each との違いは、配列ケースが引数として提供される方法です。 その他の配列以外のケース (テンプレート文字列の使用を含む) は、まったく同じように機能します。
// `each` は配列ケースを展開します
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => {
expect(a + b).toBe(expected);
});
// `for` は配列ケースを展開しません
test.for([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', ([a, b, expected]) => {
expect(a + b).toBe(expected);
});2 番目の引数は TestContext であり、たとえば同時スナップショットに使用できます。
test.concurrent.for([
[1, 1],
[1, 2],
[2, 1],
])('add(%i, %i)', ([a, b], { expect }) => {
expect(a + b).matchSnapshot();
});bench
- 型:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
Vitest において、ベンチマークとは一連の操作を定義する関数を指します。Vitest はこの関数を複数回実行して、さまざまなパフォーマンス結果を表示します。
Vitest は、内部で tinybench ライブラリを使用しており、3 番目の引数として使用できるすべてのオプションを継承しています。
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;
/**
* タスクが失敗した場合にスローします (true の場合、イベントは機能しません)
*/
throws?: boolean;
/**
* ウォームアップ時間(ミリ秒)。
* @default 100ms
*/
warmupTime?: number;
/**
* ウォームアップ処理の繰り返し回数。
* @default 5
*/
warmupIterations?: number;
/**
* 各ベンチマークタスク(サイクル)の前に実行するセットアップ関数。
*/
setup?: Hook;
/**
* 各ベンチマークタスク(サイクル)の後に実行するティアダウン関数。
*/
teardown?: Hook;
}テストケースの実行後、出力構造の情報は以下のようになります。
name hz min max mean p75 p99 p995 p999 rme samples
· normal sorting 6,526,368.12 0.0001 0.3638 0.0002 0.0002 0.0002 0.0002 0.0004 ±1.41% 652638export interface TaskResult {
/*
* タスク実行中にスローされた最後のエラー
*/
error?: unknown;
/**
* ベンチマークタスク(サイクル)実行にかかる時間(ミリ秒)
*/
totalTime: number;
/**
* サンプル中の最小値
*/
min: number;
/**
* サンプル中の最大値
*/
max: number;
/**
* 1秒あたりの操作数
*/
hz: number;
/**
* 各操作にかかる時間(ms)
*/
period: number;
/**
* 各タスク反復時間のタスクサンプル(ms)
*/
samples: number[];
/**
* サンプルの平均/平均 (母平均の推定値)
*/
mean: number;
/**
* サンプルの分散 (母分散の推定値)
*/
variance: number;
/**
* サンプルの標準偏差 (母標準偏差の推定値)
*/
sd: number;
/**
* 平均の標準誤差 (つまり、サンプル平均の標本分布の標準偏差)
*/
sem: number;
/**
* 自由度
*/
df: number;
/**
* サンプルの臨界値
*/
critical: number;
/**
* 誤差範囲
*/
moe: number;
/**
* 相対誤差範囲
*/
rme: number;
/**
* 中央絶対偏差
*/
mad: number;
/**
* p50/中央値パーセンタイル
*/
p50: number;
/**
* p75パーセンタイル
*/
p75: number;
/**
* p99パーセンタイル
*/
p99: number;
/**
* p995パーセンタイル
*/
p995: number;
/**
* p999パーセンタイル
*/
p999: number;
}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 を使用して、後で実装されるベンチマークのスタブを作成します。
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 TypeError('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 文で囲む代わりに、条件が truthy の場合にスイートをスキップするには、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';
// このスイート(および 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';
// このスイート内のすべてのスイートとテストは並行して実行されます
describe.concurrent('suite', () => {
test('concurrent test 1', async () => {
/* ... */
});
describe('concurrent suite 2', async () => {
test('concurrent test inner 1', async () => {
/* ... */
});
test('concurrent test inner 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';
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';
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
describe.todo は、後で実装するスイートのプレースホルダーを作成する際に使用します。レポートには、実装が必要なテストの数が表示されます。
// このスイートのエントリがレポートに表示されます
describe.todo('unimplemented suite');describe.each
- Alias:
suite.each
同じデータに依存する複数のテストがある場合は、describe.each を使用します。
import { describe, expect, test } from 'vitest';
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 以降では、テンプレート文字列テーブルも使用できます。
- 最初の行は、
|で区切られた列名である必要があります。 - 1 つ以上の後続のデータ行は、
${value}構文を使用してテンプレートリテラル式として記述します。
import { describe, expect, test } from 'vitest';
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 によって各テストの実行前にユーザーが追加されることが保証されます。
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 は、テストの実行前にモックデータが設定されるようにします。
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
このフックは、テストの実行が終了した後に常に呼び出されます。テスト結果に影響を与える可能性があるため、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');
});