移行ガイド
Vitest 2.0 への移行
デフォルトのプールは forks です
Vitest 2.0 では、安定性向上のため、pool のデフォルト設定が 'forks' に変更されました。詳細な動機については、PR をご参照ください。
pool を指定せずに poolOptions を使用していた場合、設定を更新する必要があるかもしれません。
export default defineConfig({
test: {
poolOptions: {
threads: {
singleThread: true,
},
forks: {
singleFork: true,
},
}
}
});フックはスタックで実行されます
Vitest 2.0 より前は、すべてのフックが並行して実行されていました。2.0 では、すべてのフックが順次実行されます。さらに、afterAll/afterEach フックは逆順に実行されます。
フックの並行実行に戻すには、sequence.hooks を 'parallel' に変更します。
export default defineConfig({
test: {
sequence: {
hooks: 'parallel',
},
},
});suite.concurrent はすべてのテストを並行して実行します
以前は、スイートで concurrent を指定すると、並行テストがスイートごとにグループ化され、順次実行されていました。現在は、Jest の動作に倣い、すべてのテストが同時に実行されます(maxConcurrency の制限に従います)。
V8 カバレッジの coverage.ignoreEmptyLines がデフォルトで有効になりました
coverage.ignoreEmptyLines のデフォルト値が true になりました。この変更はコードカバレッジレポートに影響を及ぼす可能性があり、一部のプロジェクトではカバレッジしきい値の調整が必要になる場合があります。この調整は、coverage.provider が 'v8' の場合のデフォルト設定にのみ影響します。
watchExclude オプションの削除
Vitest は Vite のウォッチャーを使用します。ファイルやディレクトリを除外するには、server.watch.ignored に追加します。
export default defineConfig({
server: {
watch: {
ignored: ['!node_modules/examplejs']
}
}
});--segfault-retry が削除されました
デフォルトのプールが変更されたため、このオプションは不要になりました。セグメンテーション違反エラーが発生した場合は、'forks' プールに切り替えてみてください。問題が解決しない場合は、再現手順を添えて新しい issue を開いてください。
スイートタスク内の空のタスクが削除されました
これは、高度なタスク API への変更です。以前は、.suite を辿っていくと、ファイルタスクの代わりに使われていた空の内部スイートに最終的に到達していました。
これにより、.suite はオプションになります。タスクがトップレベルで定義されている場合、スイートは存在しません。すべてのタスク(ファイルタスク自体も含むため、無限再帰に陥らないよう注意が必要ですが)に存在するようになった .file プロパティにフォールバックできます。
この変更により、expect.getState().currentTestName からファイルが削除され、expect.getState().testPath が必須になりました。
task.meta が JSON レポーターに追加されました
JSON レポーターは、すべてのアサーション結果に対して task.meta を出力するようになりました。
モック関数のジェネリック型が簡素化されました (例: vi.fn<T>, Mock<T>)
以前の vi.fn<TArgs, TReturn> は、引数と戻り値の型をそれぞれ別のジェネリック型として受け入れていました。これは、使用を簡略化するために、関数型 vi.fn<T> を直接受け入れるように変更されました。
import { type Mock, vi } from 'vitest';
const add = (x: number, y: number): number => x + y;
// vi.fn<T> の使用
const mockAdd = vi.fn<Parameters<typeof add>, ReturnType<typeof add>>();
const mockAdd = vi.fn<typeof add>();
// Mock<T> の使用
const mockAdd: Mock<Parameters<typeof add>, ReturnType<typeof add>> = vi.fn();
const mockAdd: Mock<typeof add> = vi.fn(); 解決済みの mock.results へのアクセス
以前の Vitest では、関数が Promise を返した場合、mock.results の値が解決されていました。現在は、返された Promise が解決または拒否された場合にのみ値が設定される、別の mock.settledResults プロパティがあります。
const fn = vi.fn().mockResolvedValueOnce('result');
await fn();
const result = fn.mock.results[0]; // 'result'
const result = fn.mock.results[0]; // 'Promise<result>'
const settledResult = fn.mock.settledResults[0]; // 'result'この変更に伴い、以前 toHaveReturned を使用していた場合の移行を容易にするために、toHaveReturned と同様の新しい toHaveResolved* マッチャーも導入されました。
const fn = vi.fn().mockResolvedValueOnce('result');
await fn();
expect(fn).toHaveReturned('result');
expect(fn).toHaveResolved('result'); ブラウザモード
Vitest ブラウザモードは、ベータサイクル中に多くの変更が行われました。ブラウザモードに関する私たちの考え方については、GitHub ディスカッションページをご覧ください。
変更のほとんどは追加的なものでしたが、いくつかの小さな破壊的変更がありました。
noneプロバイダーがpreviewにリネームされました #5842previewプロバイダーがデフォルトになりました #5842indexScriptsがorchestratorScriptsにリネームされました #5842
非推奨オプションの削除
いくつかの非推奨オプションが廃止されました。
vitest typecheckコマンド - 代わりにvitest --typecheckを使用してくださいVITEST_JUNIT_CLASSNAMEおよびVITEST_JUNIT_SUITE_NAME環境変数(代わりにレポーターオプションを使用してください)c8カバレッジのチェック(代わりに coverage-v8 を使用してください)vitestからのSnapshotEnvironmentのエクスポート - 代わりにvitest/snapshotからインポートしてくださいSpyInstanceはMockInstanceに置き換えられました
Vitest 1.0 への移行
最小要件
Vitest 1.0 は Vite 5.0 および Node.js 18 以降が必要です。
すべての @vitest/* サブパッケージは Vitest バージョン 1.0 を必要とします。
スナップショットの更新 #3961
スナップショット内の引用符はエスケープされなくなり、すべてのスナップショットは、文字列が単一行であってもバッククォート (`) を使用するようになりました。
- 引用符はエスケープされなくなりました。
expect({ foo: 'bar' }).toMatchInlineSnapshot(`
Object {
- \\"foo\\": \\"bar\\",
+ "foo": "bar",
}
`)- 1行のスナップショットは、
"ではなく "`" 引用符を使用するようになりました。
- expect('some string').toMatchInlineSnapshot('"some string"')
+ expect('some string').toMatchInlineSnapshot(`"some string"`)また、@vitest/snapshot パッケージにも変更がありました。直接使用していない場合は、何も変更する必要はありません。
equalityCheckメソッドをオーバーライドするためだけにSnapshotClientを拡張する必要がなくなりました。インスタンスを初期化する際にisEqualとして渡すだけです。client.setTestはclient.startCurrentRunにリネームされました。client.resetCurrentはclient.finishCurrentRunにリネームされました。
プールの標準化 #4172
ランナーをニーズに応じて簡単に設定できるよう、多くの設定オプションを削除しました。--threads やその他の関連フラグに依存している場合は、移行例をご参照ください。
--threadsは--pool=threadsになりました--no-threadsは--pool=forksになりました--single-threadは--poolOptions.threads.singleThreadになりました--experimental-vm-threadsは--pool=vmThreadsになりました--experimental-vm-worker-memory-limitは--poolOptions.vmThreads.memoryLimitになりました--isolateは--poolOptions.<pool-name>.isolateおよびbrowser.isolateになりましたtest.maxThreadsはtest.poolOptions.<pool-name>.maxThreadsになりましたtest.minThreadsはtest.poolOptions.<pool-name>.minThreadsになりましたtest.useAtomicsはtest.poolOptions.<pool-name>.useAtomicsになりましたtest.poolMatchGlobs.child_processはtest.poolMatchGlobs.forksになりましたtest.poolMatchGlobs.experimentalVmThreadsはtest.poolMatchGlobs.vmThreadsになりました
{
scripts: {
- "test": "vitest --no-threads"
// 同一の動作の場合:
+ "test": "vitest --pool forks --poolOptions.forks.singleFork"
// または複数の並列フォークの場合:
+ "test": "vitest --pool forks"
}
}{
scripts: {
- "test": "vitest --experimental-vm-threads"
+ "test": "vitest --pool vmThreads"
}
}{
scripts: {
- "test": "vitest --isolate false"
+ "test": "vitest --poolOptions.threads.isolate false"
}
}{
scripts: {
- "test": "vitest --no-threads --isolate false"
+ "test": "vitest --pool forks --poolOptions.forks.isolate false"
}
}カバレッジの変更 #4265, #4442
coverage.all オプションがデフォルトで有効になりました。これは、coverage.include パターンに一致するすべてのプロジェクトファイルが、実行されなくても処理されることを意味します。
カバレッジしきい値 API の形式が変更され、グロブパターンを使用して特定のファイルにしきい値を指定できるようになりました。
export default defineConfig({
test: {
coverage: {
- perFile: true,
- thresholdAutoUpdate: true,
- 100: true,
- lines: 100,
- functions: 100,
- branches: 100,
- statements: 100,
+ thresholds: {
+ perFile: true,
+ autoUpdate: true,
+ 100: true,
+ lines: 100,
+ functions: 100,
+ branches: 100,
+ statements: 100,
+ }
}
}
})モック型 #4400
Jest スタイルの「Mock」命名に合わせるため、いくつかの型が削除されました。
- import { EnhancedSpy, SpyInstance } from 'vitest'
+ import { MockInstance } from 'vitest'WARNING
SpyInstance は MockInstance に置き換えられ、次のメジャーリリースで削除されます。
タイマーモック #3925
vi.useFakeTimers() は、process.nextTick を自動的にモックしなくなりました。 vi.useFakeTimers({ toFake: ['nextTick'] }) を使用して明示的に指定することで、process.nextTick をモックすることは引き続き可能です。
ただし、--pool=forks を使用している場合、process.nextTick のモックはできません。process.nextTick のモックが必要な場合は、別の --pool オプションを使用してください。
Jest からの移行
Vitest は Jest 互換の API で設計されており、Jest からの移行を可能な限りシンプルにすることを目指しています。しかし、以下の違いに遭遇する可能性があります。
グローバルなAPIのデフォルト設定
Jest はデフォルトでグローバル API を有効にしていますが、Vitest はそうではありません。globals 設定 を介してグローバルを有効にするか、vitest モジュールからのインポートを使用するようにコードを更新することができます。
グローバルを無効にしたままにする場合、testing-library のような一般的なライブラリは、DOM の自動クリーンアップを実行しないことに注意してください。
モジュールモック
Jest でモジュールをモックする場合、ファクトリー関数の引数の戻り値はデフォルトのエクスポートです。Vitest では、ファクトリー関数の引数は各エクスポートが明示的に定義されたオブジェクトを返す必要があります。例えば、以下の jest.mock は次のように更新する必要があります。
jest.mock('./some-path', () => 'hello');
vi.mock('./some-path', () => ({
default: 'hello',
})); 詳細については、vi.mock API セクションを参照してください。
自動モックの動作
Jest とは異なり、<root>/__mocks__ 内のモックされたモジュールは、vi.mock() が呼び出されない限りロードされません。Jest のようにすべてのテストでモックする必要がある場合は、setupFiles 内でモックできます。
モックされたパッケージのオリジナルをインポートする
パッケージを部分的にモックを行っている場合、以前は Jest の関数 requireActual を使用していたかもしれません。Vitest では、これらの呼び出しを vi.importActual に置き換える必要があります。
const { cloneDeep } = jest.requireActual('lodash/cloneDeep');
const { cloneDeep } = await vi.importActual('lodash/cloneDeep'); 外部ライブラリへのモックの拡張
Jest がデフォルトで行うように、モジュールをモックし、このモックを同じモジュールを使用する他の外部ライブラリに拡張したい場合は、どのサードパーティのライブラリをモックしたいかを明示的に指定する必要があります。そのためには、server.deps.inline を使用して、外部ライブラリをソースコードの一部として扱うように設定します。
server.deps.inline: ["lib-name"]expect.getState().currentTestName
Vitest の test 名は、スイートとテストを区別しやすくするために > 記号で結合されますが、Jest は空白 () を使用します。
- `${describeTitle} ${testTitle}`
+ `${describeTitle} > ${testTitle}`環境変数
Jest と同様に、Vitest は NODE_ENV が設定されていない場合、test に設定します。Vitest には JEST_WORKER_ID に相当する VITEST_POOL_ID(常に maxThreads 以下)があります。これに依存している場合は、名前の変更を忘れないでください。Vitest はまた、実行中のワーカーのユニークな ID である VITEST_WORKER_ID も公開します。この数値は maxThreads の影響を受けず、作成されるワーカーごとに増加します。
プロパティの置換
オブジェクトを変更したい場合、Jest では replaceProperty API を使用しますが、Vitest でも同様に vi.stubEnv または vi.spyOn を使用できます。
Done コールバック
Vitest v0.10.0 以降、テストを宣言するコールバック形式は非推奨になりました。async/await 関数を使用するように書き換えるか、Promise を使用してコールバック形式を模倣できます。
it('should work', (done) => {
it('should work', () => new Promise(done => {
// ...
done()
})
})) フック
beforeAll/beforeEach フックは Vitest でティアダウン用の関数を返すことができます。そのため、undefined または null 以外を返すフックの宣言を書き換える必要があるかもしれません。
beforeEach(() => setActivePinia(createTestingPinia()));
beforeEach(() => { setActivePinia(createTestingPinia()) }); Jest ではフックは順次(一つずつ)呼び出されます。デフォルトでは、Vitest はフックを並行して実行します。Jest の動作を使用するには、sequence.hooks オプションを更新します。
export default defineConfig({
test: {
sequence: {
hooks: 'list',
}
}
});型
Vitest には jest 名前空間に相当するものが存在しないため、vitest から直接型をインポートする必要があります。
let fn: jest.Mock<(name: string) => number>;
import type { Mock } from 'vitest';
let fn: Mock<(name: string) => number>; タイマー
Vitest は Jest のレガシータイマーをサポートしていません。
タイムアウト
jest.setTimeout を使用していた場合、vi.setConfig に移行する必要があります。
jest.setTimeout(5_000);
vi.setConfig({ testTimeout: 5_000 }); Vue スナップショット
これは Jest 固有の機能ではありませんが、以前 Jest を vue-cli プリセットを使用していた場合、jest-serializer-vue パッケージをインストールし、setupFiles 内で使用する必要があります。
import { defineConfig } from 'vite';
export default defineConfig({
test: {
setupFiles: ['./tests/unit/setup.js'],
},
});import vueSnapshotSerializer from 'jest-serializer-vue';
expect.addSnapshotSerializer(vueSnapshotSerializer);そうしないと、スナップショットに多くのエスケープされた " 文字が含まれることになります。