本文へジャンプ

フロントエンド開発における自動テストの導入

Posted by YAM

フロントエンドにかかわらず開発において実装とテストは切り離せない関係にありますが、特にフロントエンド開発ではUIの変化やユーザーインタラクションが頻繁に発生するため、機能的なテストからUXの確認まで幅広いテスト、検証が必要です。しかし、レビューごとにスキルや視点が異なるため、手動テストだけでは品質の担保が難しい場合があります。そこで、MONSTER DIVEでは長期プロジェクトの安定した開発・運用の推進と、クライアントにこれまで以上の価値を提供するために、フロントエンド開発における自動テストの導入を進めています。そんな自動テストの内容の一部をご紹介します。

押さえるテスト領域

一般的なフロントエンド開発における自動テストの領域は以下のようなものがあります。

  • ユニット/統合: ロジック、分岐、動的に変わるDOMの状態。
  • 静的検査: 構文・規約・HTML構造の健全性。
  • E2E/非機能: 画面遷移、フォーム送信、アクセシビリティ、簡易パフォーマンス。
  • 視覚回帰: UIの差分検出。Storybookと併用すると効果的。
  • 入力検証: 仕様に基づく型・バリデーションをスキーマ化してテスト対象を明確化。

これらをコミット時、プルリクエスト時などタイミングに実行し網羅的にチェックすることで、品質を保ちます。2025/11月現在、以下のツールを活用しています。

ユニット/統合

ユニット/統合では「ロジックが正しい」「DOMが狙い通りに変わる」を最小単位で確認します。使うのは Vitest + jsdom。まずは分岐(null/undefined などでの早期 return)と副作用(class の付与、要素の追加/削除)を押さえ、外部ライブラリの初期化(Swiper / axios / fetch など)は vi.mock で引数や呼び出し回数を確かめます。カバレッジ目標は最初に statements 70% 程度。到達後に異常系や境界値(最大文字数、空配列、タイマー完了)を追加して厚くします。アニメーションやタイマーは vi.useFakeTimers() で時間を進めてテストを安定化します。

静的検査

ESLint / Stylelint / Prettier / Markuplint により構文・コード規約・HTML構造を事前に正規化し、ts-unused-exports で未使用の TypeScript モジュールを洗い出します。CSS 側は必要に応じて PurgeCSSで本番ビルド後の未使用セレクタを削減。これらは開発者の習熟度に依存せず自動実行できるため、CI では Lint → HTML 構造 → 未使用抽出の順で高速フィードバックを返しています。

E2E/非機能

Playwright で実ブラウザ操作(ページ遷移・フォーム送信・モーダル開閉)を確認しつつ、axe-coreで WCAG2.0/2.1 A/AA/AAA レベルのアクセシビリティ検査を行います。リンク切れは linkinator、画像サイズ過大は独自スクリプト、SEO の meta/OG/canonical/alt の有無、パフォーマンスは Lighthouse を組み込みスポットで回し、ビルド出力に対して実運用に近い動作を早期検出します。

視覚回帰

BackstopJS を用い、キャプチャ→差分テスト。閾値設定は初期はデフォルトのミスを許容し、CI で頻繁に赤が出る要素のみ safelist/ignore を調整します。コマンドでキャプチャとテストを一括実行し HTML レポートから差分を視覚的に確認します。

入力検証

Zod でメール・電話・郵便番号・氏名・ネストしたプロフィール/住所などのスキーマを定義し、safeParse により成功/失敗の両結果を型安全に扱います。エラーメッセージは日本語で一貫化し、ユニットテストでは正常値(2〜3例)、異常値(形式不正/空文字/最大超過)、境界値(最大長/最小長/任意項目省略)を網羅。スキーマを分離することで再利用性と可読性を高め、フロントとサーバー間の仕様齟齬を減らします。Zod の活用によりフォーム検証ロジックが散在せず、追加フィールドもスキーマ修正とテスト追加のみで保守性を担保できます。

UIカタログ(Storybook)

Storybook は UI の状態をカタログ化して共有するためのツールで、デザイン確認・開発者間の共通認識形成・回帰検出の土台づくりに役立ちます。ベースの開発環境ではejsベースの Storybook を採用しており、ボタンやカード、モーダルなどの代表的なコンポーネントについて、通常・ホバー・フォーカス・無効・エラー・成功といったバリアントを個別の Story として整理します。データは Args/Controls で差し替えられるようにし、長文や空文字、大量データなどの極端な状態も Story 化しておくと、設計上の破綻やスタイルのほつれを早期に見つけやすくなります。

運用では、まずは代表バリアントから始め、段階的に網羅度を上げていきます。アクセシビリティ属性(role、aria-*)は Story 上でも反映し、Playwright + axe-core によるチェック結果とズレが出ないようにします。インタラクションについては @storybook/addon-interactions を使うと、クリックや入力に応じた状態変化を Story 内で再現しやすく、手戻りの少ない UI 改修が可能です。

テストガイドライン

静的テストやパフォーマンステストはツールの設定をプロジェクトに合わせて最適化することが重要ではありますが、設定さえしてしまえばあとは自動で実行されるため、比較的導入が容易です。一方でユニットテストやE2Eテストは、何をどのようにテストするかを明確にし、チーム全体で共通認識を持つことが重要です。Vitest、Storybookは都度でテストコードやStoryを追加していく形になるため、曖昧なまま進めると「どこまで書けば良いのか」「何を優先すれば良いのか」が不明瞭になり、結果的にテストが形骸化してしまうリスクがあります。そこでガイドラインを設けてチーム全体で共有し、以下のようなポイントを押さえています。

  • テストの目的を明確にする
  • テストケースを具体的に定義する
  • テストの実行タイミングを決める
  • テスト結果を定期的にレビューする

レポーティング

テスト結果はGitHub Actionsのチェックとして表示され、失敗した場合は詳細ログとスクリーンショットが添付されます。さらに、各テストツールのレポートをHTML形式で生成し、アーティファクトとして保存。これにより、開発者は失敗の原因を迅速に特定し、修正に取り組むことができます。 また、定期的にテスト結果のサマリーレポートを自動生成し、チーム全体で共有。これにより、品質の傾向や改善点を把握し、継続的な品質向上に役立てています。

まとめ

フロントエンド開発における自動テストの導入は、品質の向上と開発効率の改善に大きく寄与します。ユニットテスト、静的検査、E2Eテスト、視覚回帰、入力検証など、多角的なアプローチで品質を担保することが重要です。また、Storybookを活用したUIカタログの作成や、明確なテストガイドラインの策定も、チーム全体での共通認識を促進し、テストの効果を最大化します。MONSTER DIVEでは、これらの取り組みを通じて、クライアントに高品質なフロントエンドソリューションを提供し続けています。今後も最新の技術動向を取り入れながら、より良い開発環境の構築を目指していきます。

Recent Entries
MD EVENT REPORT
What's Hot?