# 機能設計書 25-Integration Testing

## 概要

本ドキュメントは、Ruby on Railsの統合テスト機能の設計仕様を定義する。統合テストは、複数のコントローラにまたがるリクエスト/レスポンスのフローをテストし、コントローラ間の連携を検証する機能である。

### 本機能の処理概要

**業務上の目的・背景**：Webアプリケーションの品質保証において、個別のコントローラテストだけでは検出できない、リクエストの流れ（ログイン→操作→ログアウト等）やリダイレクトチェーン、セッション状態の遷移を検証する必要がある。統合テストは、HTTPリクエストをシミュレートし、複数のコントローラアクションを跨いだテストシナリオを実行することで、エンドツーエンドに近い検証を可能にする。

**機能の利用シーン**：ユーザー認証フロー、ECサイトの購入フロー、マルチステップフォーム、APIエンドポイントの連携テストなど、複数のHTTPリクエストを組み合わせたシナリオのテスト。ブラウザを起動しないため、システムテストより高速に実行できる。

**主要な処理内容**：
1. HTTPリクエストのシミュレート（GET/POST/PUT/PATCH/DELETE/HEAD/OPTIONS）
2. セッション・クッキー状態の管理
3. リダイレクトの追跡（follow_redirect!）
4. レスポンス検証（ステータスコード、ボディ、ヘッダー）
5. 複数セッションの同時操作（open_session）

**関連システム・外部連携**：Rack::Test gemを使用してHTTPリクエストをシミュレートする。Rack互換のミドルウェアスタックを経由するため、本番に近い動作を検証できる。

**権限による制御**：特になし。テスト環境での実行を前提とする。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 任意の画面 | 主機能 | HTTPリクエストを使用した統合テスト |

## 機能種別

テスト実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | String | Yes | リクエスト先のパス | 有効なパス形式 |
| params | Hash | No | リクエストパラメータ | - |
| headers | Hash | No | HTTPヘッダー | - |
| env | Hash | No | Rack環境変数 | - |
| xhr | Boolean | No | Ajax リクエストフラグ | true/false |
| as | Symbol | No | リクエストエンコーディング | :json 等 |

### 入力データソース

- テストコードでのget/post/put/patch/delete呼び出し
- フィクスチャデータ
- ファクトリーデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| status | Integer | HTTPステータスコード |
| response | ActionDispatch::TestResponse | レスポンスオブジェクト |
| request | ActionDispatch::Request | リクエストオブジェクト |
| cookies | Rack::Test::CookieJar | クッキー |

### 出力先

- テスト結果（標準出力/JUnit XML）
- ログファイル（test.log）

## 処理フロー

### 処理シーケンス

```
1. IntegrationTest継承クラス初期化
   └─ integration_sessionの作成
2. HTTPリクエスト発行（get/post等）
   └─ RequestEncoderでパラメータエンコード
   └─ Rack::Test::Sessionでリクエスト実行
3. レスポンス取得
   └─ ActionDispatch::TestResponseとして変換
   └─ @response, @request, @controllerに設定
4. アサーション実行
   └─ assert_response, assert_redirected_to等
5. セッション継続または終了
   └─ cookies、sessionは保持
   └─ reset!でセッションをリセット
```

### フローチャート

```mermaid
flowchart TD
    A[IntegrationTest開始] --> B[integration_session作成]
    B --> C[get/post等呼び出し]
    C --> D[RequestEncoder処理]
    D --> E[Rack::Test::Session.request]
    E --> F[Rackアプリケーション実行]
    F --> G[ActionDispatch::TestResponse作成]
    G --> H{リダイレクト?}
    H -->|Yes| I[follow_redirect!]
    I --> C
    H -->|No| J[アサーション実行]
    J --> K{次のリクエスト?}
    K -->|Yes| C
    K -->|No| L[テスト終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-25-01 | セッション継続 | 同一テスト内でセッション・クッキーを保持 | reset!が呼ばれるまで |
| BR-25-02 | デフォルトホスト | www.example.com | host未指定時 |
| BR-25-03 | HTTPSモード | https! でHTTPSリクエストをシミュレート | 明示的に呼び出した場合 |
| BR-25-04 | 307/308リダイレクト | 同一HTTPメソッドを維持 | follow_redirect!時 |

### 計算ロジック

リクエストURL構築：
```ruby
"#{env['rack.url_scheme']}://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{path}"
```

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| setup | テスト用テーブル | INSERT | フィクスチャロード |
| テスト実行 | テスト用テーブル | 各種 | アプリケーションロジックによる |
| teardown | テスト用テーブル | ROLLBACK | トランザクションロールバック |

### テーブル別操作詳細

統合テストはトランザクショナルフィクスチャを使用可能（同一プロセスで動作するため）。各テストはトランザクション内で実行され、テスト終了時にロールバックされる。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| RuntimeError | AssertionError | リダイレクトでないのにfollow_redirect!を呼んだ | レスポンスがリダイレクトか確認 |
| ActionDispatch::Http::MimeNegotiation::InvalidType | ParseError | 不正なContent-Type | リクエストヘッダーを確認 |

### リトライ仕様

統合テストはHTTPリクエストをシミュレートするため、リトライ機構は提供されない。

## トランザクション仕様

各テストはデータベーストランザクション内で実行され、テスト終了時に自動的にロールバックされる（use_transactional_tests = true の場合）。

## パフォーマンス要件

- ブラウザを起動しないため、システムテストより高速
- Rack::Testはインプロセスで動作するためオーバーヘッドが小さい
- 大量のテストケースは並列実行を推奨

## セキュリティ考慮事項

- テスト環境専用のデータベースを使用すること
- 本番環境のクレデンシャルをテストコードに含めないこと
- 外部APIを呼び出す場合はモック化を推奨

## 備考

- ブラウザを起動しないため、JavaScript の動作はテストできない
- JavaScriptを含むテストはシステムテスト（Capybara）を使用
- JSON APIのテストに特に適している

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: IntegrationTestの基本構造を理解する

統合テストの基底クラスとセッション管理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | integration.rb | `actionpack/lib/action_dispatch/testing/integration.rb` | IntegrationTest、Session、Runnerモジュール |

**読解のコツ**: IntegrationTestクラスはBehaviorモジュールをincludeし、BehaviorはIntegration::Runnerをincludeする階層構造に注目。

**主要処理フロー**:
- **15-56行目**: RequestHelpers モジュールで get/post 等を定義
- **91-333行目**: Session クラスでリクエスト処理の実装
- **226-311行目**: process メソッドが実際のリクエスト処理
- **335-452行目**: Runner モジュールでテストインターフェース提供
- **650-703行目**: IntegrationTest クラス定義

#### Step 2: リクエスト処理の詳細を理解する

HTTPリクエストのシミュレート処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | integration.rb | `actionpack/lib/action_dispatch/testing/integration.rb` | process メソッドの実装 |

**主要処理フロー**:
- **226-227行目**: RequestEncoderでリクエストエンコーディング
- **249-262行目**: リクエスト環境の構築
- **284行目**: Rack::Test::Session でリクエスト実行
- **301-304行目**: TestResponse の作成

#### Step 3: セッション管理を理解する

複数セッションの管理と状態の共有を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | integration.rb | `actionpack/lib/action_dispatch/testing/integration.rb` | open_session、reset! メソッド |

**主要処理フロー**:
- **359-361行目**: reset! でセッションをリセット
- **405-411行目**: open_session で新しいセッションを開く
- **421-427行目**: copy_session_variables! でセッション変数をコピー

### プログラム呼び出し階層図

```
IntegrationTest（テストクラス）
    │
    ├─ include Behavior (702行目)
    │      │
    │      ├─ include Integration::Runner (663行目)
    │      │      │
    │      │      ├─ integration_session (353-355行目)
    │      │      │      └─ create_session (363-373行目)
    │      │      │             └─ Integration::Session.new
    │      │      │
    │      │      └─ get/post等 (379-394行目)
    │      │             └─ integration_session.get/post
    │      │
    │      └─ include ActionController::TemplateAssertions (664行目)
    │
    └─ Integration::Session
           │
           ├─ include RequestHelpers (95行目)
           │      └─ get/post/patch/put/delete/head/options (18-56行目)
           │             └─ process (226行目)
           │
           └─ process (226行目)
                  │
                  ├─ RequestEncoder.encoder (227行目)
                  │
                  ├─ Rack::Test::Session.new (284行目)
                  │
                  └─ session.request (298行目)
                         └─ Rack アプリケーション実行
```

### データフロー図

```
[入力]                      [処理]                           [出力]

テストコード ───▶ get('/path', params: {...})
      │                    │
      │                    ▼
params ───▶ RequestEncoder ───▶ エンコード済みパラメータ
      │                    │
      │                    ▼
headers ───▶ リクエスト環境構築 ───▶ Rack env Hash
      │                    │
      │                    ▼
      │              ┌─────────────────┐
Rack app ◀────────▶ │ Rack::Test      │
      │              │ Session         │───▶ @request
      │              └─────────────────┘     @response
      │                    │                 @controller
      │                    ▼
      └──────────────▶ TestResponse作成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| integration.rb | `actionpack/lib/action_dispatch/testing/integration.rb` | ソース | 統合テスト基盤 |
| request_encoder.rb | `actionpack/lib/action_dispatch/testing/request_encoder.rb` | ソース | リクエストエンコーディング |
| test_response.rb | `actionpack/lib/action_dispatch/testing/test_response.rb` | ソース | テスト用レスポンスクラス |
| assertions.rb | `actionpack/lib/action_dispatch/testing/assertions.rb` | ソース | テストアサーション |
| test_process.rb | `actionpack/lib/action_dispatch/testing/test_process.rb` | ソース | テストプロセスヘルパー |
| page_dump_helper.rb | `actionpack/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb` | ソース | ページダンプヘルパー |
