背景:深夜2時にJestが「お荷物」になるとき
想像してみてください。深夜に本番環境の深刻なバグを修正している場面を。プレッシャーが高まる中、ようやく重要なコードを修正し、テストコマンドを叩きます。しかし、結果がすぐに出る代わりに、Jestが起動し、Babelをロードし、ファイルを変換するのを45〜60秒間もぼんやりと眺めることになります。一分一秒を争う状況で、この待ち時間はまさに苦行です。
ViteとJestを併用する際の一番の矛盾は、技術的な衝突です。ViteはES Modules (ESM) を活用して非常に高速に動作しますが、JestはデフォルトでCommonJSに固執しています。これらを繋ぐには、babel-jestからts-jestまで、複雑な設定の「迷路」を構築しなければなりません。その結果、テスト環境と実際の開発環境がかけ離れたものになってしまいます。
Vitestはこの障壁を完全に取り除く救世主として登場しました。Viteと同じトランスフォーマーを共有しているため、コードがブラウザで動くのであれば、面倒なプラグインやエイリアスの設定なしで、Vitestもそのまま処理できます。起動速度は通常ミリ秒単位で、集中力を切らすことなく作業を続けられます。
インストール:わずか3ステップでVitestを導入
もしReactやVueのプロジェクトでViteを使っているなら、Vitestの導入はJestでの苦労に比べれば格段に簡単です。迷わずターミナルを開き、以下のコマンドで遅さに別れを告げましょう:
npm install -D vitest @vitest/ui @vitest/coverage-v8 jsdom
これらのパッケージが必要な理由は以下の通りです:
- vitest: テストを実行するメインツール。
- @vitest/ui: ブラウザ上の直感的なダッシュボード。ターミナルを凝視せずにエラーを確認したい時の強い味方です。
- jsdom: ブラウザ環境をシミュレート。React/Vueコンポーネントのテストには欠かせません。
- @vitest/coverage-v8: コードのロジックを何%テストできたかを示す詳細なレポート。
インストールが完了したら、package.jsonを更新してショートカットコマンドを有効にします:
{
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest run --coverage"
}
}
実践設定:よりスムーズに動作させるための最適化
Vitestの大きな利点は、vite.config.tsをそのまま共有できることですが、よりプロフェッショナルな管理のために、独立したvitest.config.tsファイルを作成することをお勧めします。これにより、本番ビルドのロジックとテスト実行のロジックを明確に分離できます:
import { defineConfig, mergeConfig } from 'vitest/config';
import viteConfig from './vite.config';
export default mergeConfig(viteConfig, defineConfig({
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['./src/setupTests.ts'],
css: true,
},
}));
上記の設定で、globals: trueにすることで、すべてのファイルでインポートしなくてもdescribeやit関数を直接呼び出せるようになります。これにより、Jestから移行した場合でも、テストコードをクリーンで慣れ親しんだ状態に保てます。environment: 'jsdom'を使用すると、DOM操作のためのwindowやdocumentオブジェクトが利用可能になります。
React開発者の場合は、より強力なDOMテストツールを追加するためにsrc/setupTests.tsを作成しましょう:
import '@testing-library/jest-dom';
また、サポートライブラリのインストールも忘れずに行いましょう:npm install -D @testing-library/react @testing-library/jest-dom。
ヒント: 複雑なAPIデータを扱う際、私はよく toolcraft.app を使ってJSONを整形します。これによりテストファイルが格段に読みやすくなり、疲れている時のコピペミスによる構文エラーを防げます。
テストを書いて成果を実感:スピードこそがすべて
簡単な通貨フォーマット関数で実際に試してみましょう:
// src/utils/format.ts
export const formatCurrency = (amount: number) => {
return new Intl.NumberFormat('vi-VN', { style: 'currency', currency: 'VND' }).format(amount);
};
対応するテストファイル src/utils/format.test.ts を作成します:
import { formatCurrency } from './format';
describe('Utility: formatCurrency', () => {
it('ベトナムドンの記号 ₫ が正しくフォーマットされること', () => {
const result = formatCurrency(100000);
expect(result.replace(/\s/g, ' ')).toContain('₫');
});
it('値が0の時に 0 ₫ と表示されること', () => {
expect(formatCurrency(0).replace(/\s/g, ' ')).toContain('0 ₫');
});
});
npm testを実行すると、Vitestのレスポンスがほぼ瞬時であることがわかります。ウォッチモードは非常にインテリジェントで、依存関係グラフに基づいて、修正したファイルだけを再実行します。以前のように30秒待つ代わりに、コードが正しく動くかどうかを確認するのに1秒もかかりません。
さらに「リッチな」体験をしたいなら、npm run test:uiを試してみてください。何百ものテストセットを管理し、カバレッジをリアルタイムで確認し、クリック一つで各ケースをデバッグできるウェブインターフェースが表示されます。これは、テスト作成を苦行ではなく、中毒性のある楽しい作業に変えてくれる機能です。
マージ前にコードが常に正常であることを保証するために、以下のコマンドでVitestをCI/CD(GitHub Actionsなど)に組み込みましょう:
npx vitest run
このコマンドは全テストを一度実行して終了するため、自動テストプロセスに最適です。結論として、Viteを使っているなら、Jestに固執する理由はありません。Vitestはプロジェクトを高速化するだけでなく、深夜の過酷な勤務中でも、冷静さと最高のパフォーマンスを維持する助けになってくれます。

