フロントエンド自動テストとは
フロントエンド開発における「自動テスト」とは、人手を介さずにスクリプトやツールを用いて Web アプリケーションの品質を担保する仕組みである。ビジネス要件の拡大や開発メンバーの増加に伴い、コードの信頼性とリリース効率を高めるために自動テストは不可欠になっている。
テストの種類と目的
- 静的解析
ESLint/Stylelint などがコードを走査し、潜在的なバグやコーディング規約違反を検出する。設定ファイル(例:.eslintrc.js)でルールを定義して実行するだけで、コミット前に問題を摘出できる。 - ユニットテスト
最小単位(通常は関数やメソッド)の振る舞いを検証する。代表的なツールは Jest・Mocha・Vitest など。以下は Vitest を使った加算関数のテスト例である。
// math.ts
export const add = (x: number, y: number): number => x + y;
// math.test.ts
import { describe, it, expect } from 'vitest';
import { add } from './math';
describe('add()', () => {
it('2 つの数値を足し合わせる', () => {
expect(add(2, 3)).toBe(5);
});
});
- インテグレーションテスト
複数のモジュールやコンポーネントが連携して正しく動作するかを確認する。外部 API を MSW(Mock Service Worker)でモックし、ログインフォームがトークンを取得できるか検証する例を示す。
// server.ts
import { rest } from 'msw';
import { setupServer } from 'msw/node';
const server = setupServer(
rest.post('/api/login', (req, res, ctx) =>
res(ctx.json({ token: 'dummy-jwt' }))
)
);
beforeAll(() => server.listen());
afterAll(() => server.close());
// LoginForm.spec.tsx
it('ログイン成功時にトークンを保持する', async () => {
render(<LoginForm />);
await userEvent.type(screen.getByLabelText('Email'), 'test@example.com');
await userEvent.type(screen.getByLabelText('Password'), 'pass');
await userEvent.click(screen.getByRole('button', { name: 'ログイン' }));
await waitFor(() => expect(localStorage.getItem('token')).toBe('dummy-jwt'));
});
- E2E テスト
ブラウザ上で実際のユーザ操作をシミュレートし、システム全体の挙動を検証する。Playwright を使ったサンプルコードは次の通り。
import { test, expect } from '@playwright/test';
test('ユーザーが正常に登録できる', async ({ page }) => {
await page.goto('https://example.com/signup');
await page.fill('input[name="username"]', 'alice');
await page.fill('input[name="email"]', 'alice@example.com');
await page.click('button[type="submit"]');
await expect(page.locator('h1')).toContainText('登録完了');
});
- パフォーマンステスト
Lighthouse CI を CI/CD パイプラインに組み込み、各ビルドで Lighthouse スコアを取得し、閾値を下回った場合にビルドを失敗させる方法が主流である。
アサーションとは
アサーションは「期待値」と「実測値」を比較し、条件を満たさない場合にエラーを発生させる仕組みである。Node.js の組み込みモジュールでも利用できる。
import assert from 'node:assert/strict';
assert.equal(pow(2, 3), 8, 'べき乗計算が正しくない');
主要アサーションライブラリの比較
- Chai:BDD スタイル(expect/should)と古典的スタイル(assert)を選択可能。
- Jest 組み込み:toBe、toEqual、toMatchObject など直感的なマッチャーを提供。
- Power Assert:式の内容を可視化し、失敗時に詳細なメッセージを自動生成。
テストフレームワークの役割
テストフレームワークは「テストランナー」「アサーション」「モック・スパイ」「カバレッジ計測」などを一貫して提供し、開発者がテストを書きやすく実行しやすくする基盤である。
| 名称 | 特徴 | 主な用途 |
|---|---|---|
| Jest | ゼロ設定で TypeScript もサポート、スナップショット機能付き | React・Vue・Node.js ユニット/スナップショット |
| Vitest | Vite ネイティブ、高速な HMR 対応 | Vite プロジェクトのユニット |
| Cypress | ブラウザ内デバッグ、リアルタイムリロード | E2E |
| Playwright | マルチブラウザ並列実行、ヘッドレスモード高速 | E2E |
| Testing Library | DOM をユーザー目線でクエリ、実装詳細に依存しない | React・Vue・Svelte コンポーネント |
まとめ
静的解析、ユニット、インテグレーション、E2E、パフォーマンスという5層のテストピラミッドを意識し、プロジェクトフェーズに応じて適切なツールを選択することが、長期にわたって品質を維持するコツである。