Vitest 3.2 がリリースされました!
2025年6月2日
Vitest 3.2 は、ブラウザモードおよびTypeScriptサポートの改善に焦点を当てたリリースです。このリリースには新しい便利なメソッドや設定オプションが含まれ、workspace
設定は projects
に置き換えられ非推奨となりました。
workspace
は非推奨になりました
設定を簡素化するため、Vitestチームは個別の vitest.workspace
ファイルを非推奨とし、ルート設定で projects
オプションのみを使用することを推奨しています。これにより、グローバルオプションの設定も簡素化されます(ルート設定がない場合でも、レポーターの追加方法を推測する必要がなくなるため)。
また、workspace
という名前は、PNPMのようなモノレポサポートを提供する他のツールと衝突するため、非推奨とすることにしました。Vitestはこれらのプロジェクトを個別の CWD
で実行するのではなく、サブVitestとして扱います。これにより、他のツールとの互換性を保ちつつ、モノレポのためのより良いソリューションを考案する余地も生まれます。
このオプションは、将来のメジャーリリースで完全に削除され、projects
に置き換えられる予定です。それまでは、ワークスペース機能が使用されている場合、Vitestは警告を表示します。
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
// `test.workspace` は現在 `test.projects` に名称変更されました。
workspace: [
projects: [
{ test: { name: "Unit" } },
{ test: { name: "Integration" } },
],
},
});
アノテーションAPI
新しいアノテーションAPIを使用することで、任意のテストにカスタムメッセージと添付ファイルを付与できます。これらのアノテーションは、UI、HTML、junit、tap、およびGitHub Actionsのレポーターで表示されます。テストが失敗した場合、Vitestは関連するアノテーションをCLIにも出力します。

スコープ付きフィクスチャ
test.extend
フィクスチャで scope
オプション(file
または worker
)を指定できるようになりました。
const test = baseTest.extend({
db: [
async ({}, use) => {
// ...setup
await use(db);
await db.close();
},
{ scope: 'worker' },
],
});
ファイルフィクスチャは、ファイルの最上位スコープで beforeAll
と afterAll
を使用するのと似ていますが、フィクスチャがどのテストでも使用されていない場合は呼び出されません。
worker
フィクスチャはワーカーごとに1回初期化されますが、デフォルトではVitestはテストごとに1つのワーカーを作成するため、その効果を得るにはisolationを無効にする必要があります。
カスタムプロジェクト名の色
projects
を使用する際に、カスタムの色を設定できるようになりました。
設定例
export default defineConfig({
test: {
projects: [
{
test: {
name: {
label: 'unit',
color: 'red',
},
},
},
{
test: {
name: {
label: 'browser',
color: 'green',
},
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
},
],
},
})

カスタムブラウザロケーターAPI
組み込みロケーターでは、アプリケーションのニーズを表現するのに不十分な場合があります。CSSセレクターを使用するとVitestがロケーターAPIを通じて提供する再試行保護が失われるため、新しいlocators.extend
APIを使用してロケーターを拡張することをお勧めします。
import { locators } from '@vitest/browser/context';
locators.extend({
getByCommentsCount(count: number) {
return `.comments :text("${count} comments")`;
},
});
Playwrightのロケーター文字列を返して、新しいロケーターを構築します。このメソッドから返される文字列は、親ロケーターが存在する場合、その親ロケーターにスコープが設定されることに注意してください。
これで、page
または他のロケーターで getByCommentsCount
を直接呼び出すことができます。
await expect.element(page.getByCommentsCount(1)).toBeVisible();
await expect
.element(
page.getByRole('article', { name: 'Hello World' }).getByCommentsCount(1)
)
.toBeVisible();
このメソッドが文字列を返す場合、その戻り値はロケーターに変換されるため、引き続きチェーンできます。
page
.getByRole('article', { name: 'Hello World' })
.getByCommentsCount(1)
.getByText('comments');
このメソッドは現在のロケーターコンテキストにアクセスできます(メソッドが page
で呼び出された場合、コンテキストは page
を指します)。これにより、すべてのロケーターメソッドを内部でチェーンできます。
import { locators } from '@vitest/browser/context';
import type { Locator } from '@vitest/browser/context';
locators.extend({
getByCommentsCount(this: Locator, count: number) {
return this.getByRole('comment').and(this.getByText(`${count} comments`));
},
});
コンテキストにアクセスできることで、ロケーターの通常のメソッドを呼び出してカスタムユーザーイベントを定義することも可能です。
import { locators, page } from '@vitest/browser/context';
import type { Locator } from '@vitest/browser/context';
locators.extend({
clickAndFill(this: Locator, text: string) {
await this.click();
await this.fill(text);
},
});
await page.getByRole('textbox').clickAndFill('Hello World');
詳細については、locators.extend
APIを参照してください。
vi.spyOn
および vi.fn
における明示的なリソース管理
明示的なリソース管理をサポートする環境では、const
の代わりに using
を使用して、包含ブロックが終了したときにモックされた関数で mockRestore
を自動的に呼び出すことができます。これは、特にスパイされたメソッドに役立ちます。
it('calls console.log', () => {
using spy = vi.spyOn(console, 'log').mockImplementation(() => {})
debug('message')
expect(spy).toHaveBeenCalled()
})
// console.log is restored here
テスト signal
API
Vitestは、テスト関数にAbortSignal
オブジェクトを提供するようになりました。これを使用して、このWeb APIをサポートする任意のリソースを停止できます。
シグナルは、テストがタイムアウトした場合、別のテストが失敗し--bail
フラグがゼロ以外の値に設定されている場合、またはユーザーがターミナルでCtrl+Cを押した場合に中断されます。
たとえば、テストが中止されたときに fetch
リクエストを停止できます。
it('stop request when test times out', async ({ signal }) => {
await fetch('/heavy-resource', { signal });
}, 2000);
カバレッジV8 AST対応リマッピング
Vitestは、Vitestのメンテナーの一人であるAriPerkkioによって開発されたast-v8-to-istanbul
パッケージを使用するようになりました。これにより、v8カバレッジレポートがistanbulと一致するようになります。さらに、パフォーマンスも向上します!この機能を有効にするには、coverage.experimentalAstAwareRemapping
をtrue
に設定する必要があります。
次のメジャーリリースでこれをデフォルトのリマッピングモードにする予定です。古いv8-to-istanbul
は完全に削除されます。https://github.com/vitest-dev/vitest/issues/7928 で議論に参加してください。
watchTriggerPatterns
オプション
ファイルを編集すると、Vitestはそのファイルをインポートするテストだけを再実行します。残念ながら、Vitestの静的解析では静的なimport
と動的なimport
のみが考慮されます。ファイルを読み込んだり、別のプロセスを開始したりする場合、Vitestは関連ファイルの変更を無視します。
watchTriggerPatterns
オプションを使用すると、変更されたファイルに基づいてどのテストを再実行するかを設定できます。たとえば、テンプレートが変更されたときに常に mailers
テストを再実行するには、トリガーパターンを追加します。
export default defineConfig({
test: {
watchTriggerPatterns: [
{
pattern: /^src\/templates\/(.*)\.(ts|html|txt)$/,
testsToRun: (file, match) => {
return `api/tests/mailers/${match[2]}.test.ts`;
},
},
],
},
});
新しい多目的 Matchers
型
Vitestには、すべてのカスタムマッチャーの型サポートを1か所で追加するために拡張できる Matchers
型が追加されました。この型は、次のすべてのユースケースに影響を与えます。
expect().to*
expect.to*
expect.extend({ to* })
たとえば、型安全な toBeFoo
マッチャを実装するには、次のように記述できます。
import { expect } from 'vitest';
interface CustomMatchers<R = unknown> {
toBeFoo: (arg: string) => R;
}
declare module 'vitest' {
interface Matchers<T = any> extends CustomMatchers<T> {}
}
expect.extend({
toBeFoo(actual, arg) {
// ^?
// ... implementation
return {
pass: true,
message: () => '',
};
},
});
expect('foo').toBeFoo('foo');
expect.toBeFoo('foo');
sequence.groupOrder
新しいsequence.groupOrder
オプションは、複数のプロジェクトを使用する際に、プロジェクトがテストを実行する順序を制御します。
- 同じグループオーダー番号を持つプロジェクトは一緒に実行され、グループは番号の低い順から高い順に実行されます。
- このオプションが設定されていない場合、すべてのプロジェクトは並行して実行されます。
- 複数のプロジェクトが同じグループオーダーを指定した場合、それらは同時に実行されます。
例
この例を見てみましょう。
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
projects: [
{
test: {
name: 'slow',
sequence: {
groupOrder: 0,
},
},
},
{
test: {
name: 'fast',
sequence: {
groupOrder: 0,
},
},
},
{
test: {
name: 'flaky',
sequence: {
groupOrder: 1,
},
},
},
],
},
});
これらのプロジェクトのテストは、以下の順序で実行されます。
0. slow |
|> running together
0. fast |
1. flaky |> runs after slow and fast alone
変更点の完全なリストは、Vitest 3.2 Changelogにあります。