移行ガイド
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(); // fake
vi.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);
そうしないと、スナップショットに多くのエスケープされた "
文字が含まれることになります。