Viteネイティブなテスト環境がもたらす開発速度の跳ね上がり
フロントエンドのテストといえば長年Jestが主流でしたが、設定の複雑さやオーバーヘッドが課題でした。Viteの設定を共有する「Vitest」と「React Testing Library」を組み合わせることで、爆速のテスト環境が手に入ります。
保守性が高く壊れにくいテストスイートを構築するための実戦原則をまとめました。
原則:「実装の詳細」ではなく「ユーザーの振る舞い」をテストする
コンポーネントの内部stateを直接テストすると、リファクタリングのたびに壊れる脆いテストになります。ユーザーに見える画面の振る舞いを検証するのが基本です。
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { LoginForm } from './LoginForm';
test('入力からログイン完了までのフローを検証', async () => {
const user = userEvent.setup();
render(<LoginForm />);
await user.type(screen.getByLabelText('メールアドレス'), 'test@example.com');
await user.click(screen.getByRole('button', { name: 'ログイン' }));
expect(await screen.findByText('ようこそ')).toBeInTheDocument();
});
非同期更新での落とし穴:クエリ関数の使い分け
getBy*: 要素が「今すぐ存在する」ことを同期検証。存在しない場合は即座にエラー。findBy*: API取得など「非同期で遅れて表示される」要素を待機(Promiseを返す)。queryBy*: 要素が「画面に存在しないこと」をアサートする際に使用(nullを返す)。
CI実行時間を削減する並列化のポイント
Vitestはデフォルトでスレッド並列実行を行います。DOM操作を伴うテストでは、テストケースごとに独立性を保つよう afterEach で適切にモックをリセットし、テスト並列数を最大化してCIコストを抑えましょう。

