2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptにおけるテスト戦略:単体テストと統合テストの設計的な住み分け

Posted at

概要

テストは単なる「確認作業」ではない。
それは**“ソフトウェアが意図通りに動き続けるための設計支援ツール”**である。

JavaScriptにおいて、単体テストと統合テストをどう設計し、どう住み分けるかは、

  • モジュール構造
  • 責務の分離
  • 副作用の制御
    と密接に関係する。

本稿では、テスト戦略を設計レベルで分解し、単体/統合テストの役割・設計・判断基準を明確にしていく。


1. 単体テストの目的と設計指針

// math.ts
export const sum = (a, b) => a + b;
// math.test.ts
test('sum of 1 and 2 is 3', () => {
  expect(sum(1, 2)).toBe(3);
});
  • ✅ 関数単位で入力 → 出力が決まっているものに適用
  • ✅ 副作用なし、外部依存なしの純粋な処理に対して有効
  • ✅ リファクタリングの安全性を担保する

2. 統合テストの目的と設計指針

// API連携 + ストア更新 + UI描画の一連の動作を検証
test('user login flow', async () => {
  render(<Login />);
  userEvent.type(screen.getByLabelText('Email'), 'test@example.com');
  userEvent.click(screen.getByText('Login'));

  await waitFor(() => {
    expect(screen.getByText('Welcome')).toBeInTheDocument();
  });
});
  • ✅ 複数のモジュールを現実的な形で連結して検証
  • ✅ 副作用(API、ストレージ、ルーティング)を含めて確認
  • ✅ バグの再現性とシナリオレベルの担保に向いている

3. それぞれの役割と設計的な境界

項目 単体テスト 統合テスト
対象 関数・クラス・モジュール単位 機能全体・ページ・画面遷移
副作用の有無 原則なし(MockやStubで分離) 原則あり(実API or MSW/DB連携)
検証粒度 小さい・ピンポイント 大きい・ユースケースベース
実装変更への耐性 高い(テスタブルな設計が前提) 中程度(構造変更に影響を受けやすい)
バグ検知力 ロジック・境界値・例外に強い 繋がりの不整合・想定外フローに強い

4. 単体と統合を接続する設計:責務分離と依存制御

// usecase.ts
export function registerUser(apiClient, validator, userData) {
  if (!validator(userData)) throw new Error('Invalid');
  return apiClient.post('/register', userData);
}
  • ✅ 単体テスト:validator と apiClient を Mock に差し替えて検証
  • ✅ 統合テスト:DIで依存を差し替えず、実ロジックの流れを通す

5. テストの優先度とカバレッジ設計

- 重要なロジック・計算 → 単体テストで網羅
- ユーザーの操作フロー → 統合テストでシナリオ検証
- インフラとの接続部分 → モック or 実接続でエッジテスト
  • ✅ 「すべてをテストする」のではなく、目的に応じた最小構成で安定を担保
  • ✅ テストしやすさを基準に設計を見直すことが、テストコストと品質の両立につながる

設計判断フロー

① 関数の出力は入力に依存しているか? → 単体テスト

② モジュール間の接続部分に不安があるか? → 統合テスト

③ 外部依存は明示的か? → Mock可能なら単体、不可なら統合

④ ユーザー操作からのエンドツーエンド確認が必要か? → 統合テスト

⑤ 実装変更に強いテストが必要か? → 単体テストを重視

よくあるミスと対策

❌ 統合テストだけ書いて「落ちた原因が特定できない」

→ ✅ 統合 → 単体へと掘り下げて書く。階層別に分離して整備。


❌ 単体テストでMockを使いすぎて本番挙動と乖離

→ ✅ Mockは「契約が安定している依存」に限定する


❌ テストが通ってもバグが混入する

→ ✅ 「確認したい事実」に対してテストが明示的か確認する


結語

テストを書くことはゴールではない。
それは**“設計を洗練させ、変更に強く、意図を保証できるシステムを育てるための構造戦略”**である。

  • 単体テストは、設計を明示し、モジュールを独立させる
  • 統合テストは、現実のフローを通して一貫性を確認する
  • どちらをいつ使うかは「テストしやすさ」ではなく「設計目的」で判断する

JavaScriptにおけるテスト戦略とは、
“確認のためではなく、進化するソフトウェアを支える設計基盤である。”

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?