mcpField
V
vitest-v4

vitest-v4

github.com/nodnarbnitramテスト・品質1662 回インストール27 週間前に更新
リポジトリ

vitest-v4 について

テストスイートの作成、設定、デバッグを行う開発者向けのVitest 4スキルです。Viteネイティブな手法に加え、実行、モック、カバレッジ、ブラウザテスト、複数プロジェクト設定を扱います。

主な機能

  1. 01Vitest 4の設定ガイダンス
  2. 02モックとクリーンアップのパターン
  3. 03カバレッジ設定
  4. 04Browser Modeでのテスト
  5. 05複数プロジェクト設定

活用シーン

  1. 01CIでウォッチなしのテストを実行
  2. 02テスト間に残るモックの修正
  3. 03未テストファイルのカバレッジ設定
  4. 04Browser Modeのスパイ問題の調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/nodnarbnitram/claude-code-extensions --skill vitest-v4

インストール後、Claude Code で/vitest-v4を入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
references/
browser-mode-reference.md
coverage-projects-reference.md
mocking-reference.md
pools-execution-reference.md
README.md

詳細

Vitest 4 テストスキル

Vite ネイティブのパターンを使って、Vitest 4 のテストスイートを作成、設定、デバッグします。

開始する前に

このスキルを使うと、Vitest 4 でよくある 7 つ以上のミスを防ぎ、トークンを約 50%節約できます。

指標スキルなしスキルあり
セットアップ時間約 90 分約 30 分
よくあるエラー7 以上0
トークン使用量多い(試行錯誤)少ない(既知のパターン)
このスキルで防げる既知の問題
  1. vitest run ではなくウォッチモードを使うことによる、エージェントの実行停止
  2. 削除された coverage.all や coverage.extensions を使うことによる、カバレッジ設定の破損
  3. シールされた ESM 名前空間オブジェクトによる、Browser Mode のスパイ失敗
  4. restore/reset 設定の不足による、テスト間でのモックの漏洩
  5. 非推奨の workspace 用語を使うことによる、無効なマルチプロジェクト設定
  6. Jest のヘルパーを Vitest のテストに混在させることによる、誤った API の使用
  7. vitest/browser ではなく合成ヘルパーを使うことによる、不安定なブラウザー操作
  8. 不適切な実行プールや分離モードの選択による、大規模なテストスイートの実行低速化や不安定化

クイックスタート

ステップ 1:エージェントに安全な実行のために Vitest 4 を設定する
// vitest.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    environment: 'node',
    restoreMocks: true,
    clearMocks: true,
    coverage: {
      provider: 'v8',
      include: ['src/**/*.{ts,tsx}'],
    },
  },
});

重要な理由: Vitest 4 では coverage.all と coverage.extensions が削除されました。また、エージェントや CI 環境では、1 回限りの実行とモックの自動クリーンアップが必要です。

ステップ 2:Jest API ではなく Vitest API でテストを書く
import { describe, expect, it, vi } from 'vitest';
import { addUser } from './add-user';
import * as api from './api';

describe('addUser', () => {
  it('returns the created user', async () => {
    vi.spyOn(api, 'createUser').mockResolvedValue({ id: '1', name: 'Ada' });

    await expect(addUser('Ada')).resolves.toEqual({ id: '1', name: 'Ada' });
  });
});

重要な理由: モック API としてサポートされているのは vi です。jest.fn() や Jest 専用のパターンを混在させると、分かりにくいエラーが発生し、オートコンプリートの質も低下します。

インポートのルール: プロジェクトで globals: true が明示的に有効になっている場合を除き、describe、it、expect、vi は vitest からインポートしてください。

ステップ 3:正しいランタイムコマンドを使う
vitest run
vitest run --coverage
vitest run path/to/example.test.ts

重要な理由: 開発時に run を付けずに vitest を実行すると、デフォルトでウォッチモードが起動します。これはエージェント、CI、非対話型の検証には適していません。

重要なルール

必ず行うこと
  • エージェントや CI のワークフローでは、vitest run または vitest --no-watch を使します
  • 型安全なモジュールモックには、vi.mock(import('./module')) を優先します
  • restoreMocks、clearMocks、または mockReset を意図的に設定します
  • マルチプロジェクト設定には projects を使います。この名称への変更は Vitest 3.2 で始まり、以前のワークスペースファイルの使用方法は Vitest 4 で削除されています
  • 複数の projects で共通設定が必要な場合は、共有のベース設定を使います。明示的にオプトインしない限り、プロジェクトはルート設定を継承しません
  • テストされていないソースファイルもレポートに含めるには、coverage.include を使います
  • Browser Mode では、vitest/browser の page と userEvent を使います
  • 生の速度よりもネイティブモジュールやランタイムとの互換性が重要な場合は、forks を優先します
  • AI にテストを生成させるときは、vitest.config.ts と実装ファイルを共有します
絶対にしてはいけないこと
  • Vitest のコードで jest.fn、jest.spyOn、または Jest 専用のグローバルを使わないでください
  • Vitest 4 で削除された coverage.all や coverage.extensions に依存しないでください
  • エージェント主導の検証で、通常のウォッチモードを使わないでください
  • Browser Mode でネイティブ ESM のエクスポートに vi.spyOn を使わないでください
  • vi.mock() はファイル内の残りのコードが実行される前に巻き上げられることを忘れないでください
  • テスト間で環境変数やグローバルのスタブを復元し忘れないでください
よくある間違い

誤り — 削除されたカバレッジオプション:

export default defineConfig({
  test: {
    coverage: {
      all: true,
    },
  },
});

正しい方法 — include グロブを使う:

export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      include: ['src/**/*.{ts,tsx}'],
    },
  },
});

理由: Vitest 4 では coverage.all と coverage.extensions が削除されています。未カバーのファイルを含めるには、サポートされている方法である coverage.include を使います。

誤り — Browser Mode でシールされたエクスポートをスパイする:

import * as math from './math';
import { vi } from 'vitest';

vi.spyOn(math, 'add').mockReturnValue(10);

正しい方法 — スパイを有効にしたモジュールモックを使う:

import { vi } from 'vitest';

vi.mock(import('./math'), { spy: true });

理由: ネイティブのブラウザー ESM 名前空間オブジェクトはシールされているため、Browser Mode ではエクスポートに直接スパイを設定できません。

既知の問題の予防

問題根本原因解決策
テストが終了しない非対話型セッションでウォッチモードが開始されたvitest run を使用します
カバレッジレポートに未テストのファイルが表示されないcoverage.include が設定されていないソースを明示的に指定するグロブを追加します
Browser Mode のスパイが例外をスローする、または何もしないシールされた ESM エクスポートに vi.spyOn を使用しているvi.mock(import('./mod'), { spy: true }) を使用します
モックがテスト間で漏れるクリーンアップ用フラグがないrestoreMocks / clearMocks / unstubEnvs を有効にします
アップグレード後に複数プロジェクトの設定が壊れる非推奨の workspace 用語、または削除された workspace ファイルパターンを引き継いでいるprojects と defineProject に切り替えます
ワーカーまたはプールの設定が機能しなくなる古い maxThreads、maxForks、または poolOptions を引き継いでいるmaxWorkers などの Vitest 4 のワーカー設定に移行します
プロジェクト固有の設定が予期せず消えるルート設定の前提が projects に継承されていないextends: true、mergeConfig、または明示的に共有ベース設定を使用します
AI が生成したテストで誤ったヘルパーが使われるJest のパターンが Vitest にコピーされているvi、Vitest のインポート、Vitest のマッチャーに置き換えます
ブラウザテストがハングするダイアログが処理をブロックしている、または誤った user-event ユーティリティを使っているダイアログをモックし、vitest/browser のヘルパーを使用します
高速なプールでネイティブモジュールに奇妙な問題が発生するプロセス分離が必要なテストスイートに threads を選択しているforks に切り替えるか、スレッドの使用範囲を絞ります

バンドルされたリソース

リファレンス

設定リファレンス

vitest.config.ts
import { defineConfig, defineProject } from 'vitest/config';
import { playwright } from '@vitest/browser-playwright';

export default defineConfig({
  test: {
    projects: [
      defineProject({
        test: {
          name: 'unit',
          include: ['src/**/*.test.ts'],
          environment: 'node',
        },
      }),
      defineProject({
        test: {
          name: 'browser',
          include: ['src/**/*.browser.test.ts'],
          browser: {
            enabled: true,
            provider: playwright(),
            instances: [{ browser: 'chromium' }],
          },
        },
      }),
    ],
    coverage: {
      provider: 'v8',
      include: ['src/**/*.{ts,tsx}'],
    },
    restoreMocks: true,
    unstubEnvs: true,
    setupFiles: ['./test/setup.ts'],
  },
});

主な設定:

  • test.projects:安定した複数プロジェクト向けの用語です。名称変更は Vitest 3.2 で始まり、プロジェクトはルート設定のすべての値を自動的に継承するわけではないため、必要に応じて共有設定を再利用するベースにまとめてください
  • coverage.include:カバレッジ対象外のソースファイルをレポートに表示する必要がある場合に必須です
  • browser.provider:Vitest 4 では、playwright() などのプロバイダーパッケージからプロバイダーファクトリーをインポートします
  • restoreMocks / unstubEnvs:ファイル間でのテストの汚染を防ぎます
  • setupFiles:テストファイルの実行前に、MSW、グローバル変数、ポリフィルなどの共有テスト初期化を実行します

プロジェクト構成

my-app/
├── src/
│   ├── feature.ts
│   ├── feature.test.ts
│   └── feature.browser.test.ts
├── vitest.config.ts
├── vite.config.ts
└── package.json

重要な理由: Node と Browser Mode のテストを明確に分けることで、プロバイダーの設定、テストの選択、トラブルシューティングが大幅に簡単になります。

適切な環境を選択する: ほとんどのコンポーネントテストや軽量な DOM アサーションには jsdom を優先してください。ネイティブのブラウザー API、実際のレイアウトやイベントの動作、またはスクリーンショットのアサーションが重要な場合は、Browser Mode を使用してください。

適切な実行モデルを選択する: 安定性とネイティブモジュールとの互換性を重視し、特に複数の環境が混在するテストスイートやインフラストラクチャーに依存するテストスイートでは forks を優先してください。threads は、テスト環境がワーカースレッドでの実行に安全であり、追加の速度に価値があると分かっている場合にのみ使用してください。

よくあるパターン

型安全なモジュールモックのパターン
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { getUserName } from './get-user-name';
import * as api from './api';

vi.mock(import('./api'), () => ({
  fetchUser: vi.fn(),
}));

describe('getUserName', () => {
  beforeEach(() => {
    vi.mocked(api.fetchUser).mockReset();
  });

  it('returns the fetched user name', async () => {
    vi.mocked(api.fetchUser).mockResolvedValue({ id: '1', name: 'Ada' });

    await expect(getUserName('1')).resolves.toBe('Ada');
  });
});
Browser Mode の操作パターン
import { expect, test } from 'vitest';
import { page, userEvent } from 'vitest/browser';
import { render } from 'vitest-browser-react';
import { Counter } from './counter';

test('increments after click', async () => {
  render(<Counter />);

  await userEvent.click(page.getByRole('button', { name: /increment/i }));

  await expect.element(page.getByText('1')).toBeInTheDocument();
});
インソーステストのパターン
export function sum(a: number, b: number) {
  return a + b;
}

if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest;

  it('adds numbers', () => {
    expect(sum(1, 2)).toBe(3);
  });
}

依存関係

必須
パッケージバージョン用途
vitest^4テストランナーとアサーション/モック API
vite^6Vite を利用した共有モジュールパイプライン
node>=20Vitest 4 に必要なランタイム
オプション
パッケージバージョン用途
@vitest/coverage-v8^4AST リマッピングによる高速かつ正確なカバレッジ
@vitest/coverage-istanbul^4Istanbul カバレッジバックエンド
@vitest/browser-playwright^4Browser Mode 用の Playwright プロバイダー
@vitest/browser-webdriverio^4Browser Mode 用の WebdriverIO プロバイダー
@vitest/browser-preview^4Browser Mode 用のプレビュープロバイダー

公式ドキュメント

トラブルシューティング

エージェントの実行がいつまでも終了しない

症状: テストプロセスが終了しない、または Claude が追加のファイル変更を待ち続けます。

解決策:

vitest run
Browser Mode のテストでエクスポートをスパイできない

症状: vi.spyOn() が例外をスローする、何もしない、または Node モードでは動作するのにブラウザーでは失敗します。

解決策:

vi.mock(import('./module'), { spy: true });
カバレッジにテストのないソースファイルが含まれない

症状: レポートに、実行したテストで触れたファイルしか含まれません。

解決策:

coverage: {
  provider: 'v8',
  include: ['src/**/*.{ts,tsx}'],
}
アップグレード後に従来のワーカーまたはプールの設定が機能しない

症状: Vitest 4 への移行後、古い maxThreads、maxForks、singleThread、singleFork、または poolOptions の設定が機能しなくなります。

解決策:

test: {
  maxWorkers: 4,
}

理由: Vitest 4 ではワーカー設定が簡素化され、プール固有の古いオプションがいくつか削除されました。

セットアップチェックリスト

このスキルを使用する前に、次の項目を確認してください。

  • Node.js が >=20 である
  • vite が >=6 である
  • vitest.config.ts または vite.config.ts に test ブロックが含まれている
  • エージェント/CI のコマンドで vitest run を使用している
  • カバレッジが有効な場合、カバレッジプロバイダーのパッケージがインストールされている
  • Browser Mode が有効な場合、ブラウザープロバイダーのパッケージがインストールされている

コメント