移行ガイド
Vitest 3.0 への移行
test オプションを第3引数として渡す
Vitest 3.0 では、test または describe 関数にオブジェクトを第3引数として渡すと警告が表示されるようになりました。
test('validation works', () => {
// ...
}, { retry: 3 });
test('validation works', { retry: 3 }, () => {
// ...
});次のメジャーバージョンでは、第3引数がオブジェクトの場合、エラーがスローされます。ただし、タイムアウトの数値は非推奨ではありません。
test('validation works', () => {
// ...
}, 1000); // Ok ✅browser.name と browser.providerOptions は非推奨です
browser.name と browser.providerOptions は Vitest 4 で削除されます。代わりに、新しい browser.instances オプションを使用してください。
export default defineConfig({
test: {
browser: {
name: 'chromium',
providerOptions: {
launch: { devtools: true },
},
instances: [
{
browser: 'chromium',
launch: { devtools: true },
},
],
},
},
})新しい browser.instances フィールドを使用すると、複数のブラウザ設定を指定できます。
spy.mockReset が元の実装を復元するようになりました
以前は、スパイを再適用せずに元の実装にリセットする良い方法がありませんでした。spy.mockReset は、モック関数を元の実装にリセットするようになりました。
const foo = {
bar: () => 'Hello, world!',
};
vi.spyOn(foo, 'bar').mockImplementation(() => 'Hello, mock!');
foo.bar(); // 'Hello, mock!'
foo.bar.mockReset();
foo.bar(); // undefined
foo.bar(); // 'Hello, world!'vi.spyOn はメソッドがすでにモックされている場合、モックを再利用します
以前は、Vitest はオブジェクトをスパイする際、常に新しいスパイを割り当てていました。これにより、mockRestore でエラーが発生しました。これは、スパイが元の関数ではなく以前のスパイに復元されていたためです。
vi.spyOn(fooService, 'foo').mockImplementation(() => 'bar');
vi.spyOn(fooService, 'foo').mockImplementation(() => 'bar');
vi.restoreAllMocks();
vi.isMockFunction(fooService.foo); // true
vi.isMockFunction(fooService.foo); // false擬似タイマーのデフォルト
Vitest は fakeTimers.toFake オプションのデフォルト値を提供しなくなりました。Vitest は、利用可能なタイマー関連の API をすべてモックするようになりました(nextTick を除く)。具体的には、vi.useFakeTimers が呼び出されると、performance.now() もモックされるようになりました。
vi.useFakeTimers();
performance.now(); // original
performance.now(); // fakevi.useFakeTimers を呼び出すときにタイマーを指定するか、設定でグローバルに指定することで、以前の動作に戻すことができます。
export default defineConfig({
test: {
fakeTimers: {
toFake: [
'setTimeout',
'clearTimeout',
'setInterval',
'clearInterval',
'setImmediate',
'clearImmediate',
'Date',
]
},
},
})より厳密なエラーの等価性
Vitest は、toEqual または toThrowError を介してエラーを比較する際に、より多くのプロパティをチェックするようになりました。具体的には、name、message、cause、および AggregateError.errors を比較します。Error.cause の場合、比較は非対称に行われます。
expect(new Error('hi', { cause: 'x' })).toEqual(new Error('hi')); // ✅
expect(new Error('hi')).toEqual(new Error('hi', { cause: 'x' })); // ❌より多くのプロパティチェックに加えて、Vitest はエラーのプロトタイプも比較するようになりました。たとえば、TypeError がスローされた場合、等価性チェックは Error ではなく TypeError を参照する必要があります。
expect(() => {
throw new TypeError('type error');
})
.toThrowError(new Error('type error'))
.toThrowError(new TypeError('type error')); 詳細については、プルリクエスト #5876 を参照してください。
Vite 6 では module 条件エクスポートはデフォルトで解決されません
Vite 6 では、より柔軟な resolve.conditions オプションが利用可能になり、Vitest はデフォルトで module 条件エクスポートを除外するように設定されています。 Vite 側の変更の詳細については、Vite 6 移行ガイドも参照してください。
Custom 型は非推奨です API
Custom 型は Test 型のエイリアスになりました。Vitest は 2.1 で公開型を更新し、エクスポート名を RunnerCustomCase と RunnerTestCase に変更しました。
import {
RunnerCustomCase,
RunnerTestCase,
} from 'vitest';getCurrentSuite().custom() を使用している場合、返されるタスクの type は 'test' になります。Custom 型は Vitest 4 で削除されます。
WorkspaceSpec 型は使用されなくなりました API
公開 API では、この型は以前はカスタムの シーケンサー で使用されていました。代わりに TestSpecification に移行してください。
onTestFinished と onTestFailed がコンテキストを受け取るようになりました
onTestFinished と onTestFailed フックは、以前は最初の引数としてテスト結果を受け取っていました。現在は、beforeEach や afterEach と同様に、テストコンテキストを受け取るようになりました。
スナップショット API の変更点 API
@vitest/snapshot の公開スナップショット API は、単一の実行内で複数の状態をサポートするように変更されました。詳細については、プルリクエスト #6817 を参照してください。
この変更は、スナップショット API を直接使用する開発者にのみ影響を与えます。.toMatchSnapshot API に変更はありません。
resolveConfig 型シグネチャの変更点 API
resolveConfig はより便利になりました。すでに解決された Vite 設定を受け入れる代わりに、ユーザー設定を受け入れ、解決された設定を返します。
この関数は内部では使用されず、公開 API としてのみ公開されています。
vitest/reporters 型のクリーンアップ API
vitest/reporters エントリポイントは、レポーターの実装とオプション型のみをエクスポートするようになりました。TestCase/TestSuite およびその他のタスク関連の型にアクセスする必要がある場合は、vitest/node から追加でインポートしてください。
coverage.excludes が上書きされても、カバレッジはテストファイルを無視します。
coverage.excludes を上書きしても、テストファイルをカバレッジレポートに含めることはできなくなりました。テストファイルは常に除外されます。
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> は引数と戻り値に対して2つのジェネリック型を別々に受け入れていました。これは、使用を簡素化するために、関数型 vi.fn<T> を直接受け入れるように変更されました。
import { vi } from 'vitest';
import type { Mock } from 'vitest';
const add = (x: number, y: number): number => x + y;
// using vi.fn<T>
const mockAdd = vi.fn<Parameters<typeof add>, ReturnType<typeof add>>();
const mockAdd = vi.fn<typeof add>();
// using Mock<T>
const mockAdd: Mock<Parameters<typeof add>, ReturnType<typeof add>> = vi.fn();
const mockAdd: Mock<typeof add> = vi.fn(); 解決された mock.results へのアクセス
以前は、関数が Promise を返した場合、Vitest は 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"
// For identical behaviour:
+ "test": "vitest --pool forks --poolOptions.forks.singleFork"
// Or multi parallel forks:
+ "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 からの移行を可能な限りシンプルにすることを目的としています。これらの努力にもかかわらず、以下の違いに遭遇する可能性があります。
デフォルトとしてのグローバル
Jest はデフォルトでグローバル API を有効にしています。Vitest はそうではありません。globals 設定 を介してグローバルを有効にするか、vitest モジュールからのインポートを使用するようにコードを更新することができます。
グローバルを無効にしたままにする場合、testing-library のような一般的なライブラリは、DOM のクリーンアップ を自動的に実行しないことに注意してください。
spy.mockReset
Jest の mockReset は、モックの実装を undefined を返す空の関数に置き換えます。
Vitest の mockReset は、モックの実装を元のものにリセットします。 つまり、vi.fn(impl) で作成されたモックをリセットすると、モックの実装は impl にリセットされます。
モジュールモック
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 は VITEST_WORKER_ID も公開しています。これは実行中のワーカーの一意の 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 パッケージをインストールし、セットアップファイル 内で使用する必要があります。
import { defineConfig } from 'vite';
export default defineConfig({
test: {
setupFiles: ['./tests/unit/setup.js'],
},
});import vueSnapshotSerializer from 'jest-serializer-vue';
expect.addSnapshotSerializer(vueSnapshotSerializer);そうしないと、スナップショットに多くのエスケープされた " 文字が含まれることになります。