# 機能設計書 24-System Testing

## 概要

本ドキュメントは、Ruby on Railsのシステムテスト機能の設計仕様を定義する。システムテストは、実際のブラウザを使用してアプリケーション全体を統合的にテストする機能であり、JavaScript を含むユーザー操作をシミュレートできる。

### 本機能の処理概要

**業務上の目的・背景**：Webアプリケーションの品質保証において、個々のユニットテストや統合テストだけでは検出できないブラウザ固有の問題やJavaScript動作の検証が必要である。システムテストは、実際のブラウザ環境でユーザー操作をシミュレートし、エンドツーエンドでアプリケーションの動作を検証することで、本番環境に近い状態でのテストを可能にする。

**機能の利用シーン**：フォーム送信、ページ遷移、Ajax操作、モーダルダイアログ、ファイルアップロードなど、ブラウザ上でのユーザー操作を伴う機能のテスト。特にJavaScriptによる動的な画面更新やSPA（Single Page Application）の動作確認に有効。

**主要な処理内容**：
1. Capybaraを基盤としたテストDSLの提供
2. Selenium WebDriver / Cuprite / Playwright などのブラウザドライバー統合
3. テスト用サーバーの起動（Puma/WEBrick）
4. スクリーンショット自動撮影（テスト失敗時）
5. ブラウザのセットアップとティアダウン

**関連システム・外部連携**：Capybara gem（テストDSL）、Selenium WebDriver（ブラウザ自動化）、Chrome/Firefox/Safari（実ブラウザ）、Cuprite/Playwright（ヘッドレスブラウザ）と連携する。

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

## 関連画面

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

## 機能種別

テスト実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| driver | Symbol | Yes | ブラウザドライバー名 | :selenium, :cuprite, :rack_test, :playwright |
| using | Symbol | No | 使用するブラウザ | :chrome, :firefox, :headless_chrome, :headless_firefox |
| screen_size | Array | No | ブラウザウィンドウサイズ | [width, height] 形式 |
| options | Hash | No | ドライバー固有オプション | ドライバーによる |

### 入力データソース

- テストクラスでのdriven_by宣言
- application_system_test_case.rb でのデフォルト設定
- 環境変数（CAPYBARA_INLINE_SCREENSHOT等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| test_result | Boolean | テスト成功/失敗 |
| screenshot | File | スクリーンショット画像（失敗時） |
| html_snapshot | File | HTML スナップショット（オプション） |

### 出力先

- テスト結果（標準出力/JUnit XML）
- スクリーンショット（tmp/screenshots/）
- HTMLスナップショット（tmp/screenshots/）

## 処理フロー

### 処理シーケンス

```
1. テストクラス初期化
   └─ driven_by でドライバー設定
   └─ Capybara.app にRailsアプリケーションをマウント
2. テストサーバー起動
   └─ SystemTesting::Server.new.run
3. 各テストケース実行
   └─ setup: ブラウザセッション開始
   └─ test実行: Capybara DSL でブラウザ操作
   └─ teardown: スクリーンショット撮影（失敗時）、セッションリセット
4. テスト終了
   └─ ブラウザ終了
```

### フローチャート

```mermaid
flowchart TD
    A[SystemTestCase継承クラス] --> B[driven_by 設定]
    B --> C[Driver.new でドライバー初期化]
    C --> D{ドライバータイプ?}
    D -->|selenium| E[Selenium WebDriver登録]
    D -->|cuprite| F[Cuprite登録]
    D -->|rack_test| G[RackTest登録]
    D -->|playwright| H[Playwright登録]
    E --> I[テストサーバー起動]
    F --> I
    G --> I
    H --> I
    I --> J[テストケース実行]
    J --> K{テスト成功?}
    K -->|No| L[スクリーンショット撮影]
    K -->|Yes| M[次のテストへ]
    L --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-24-01 | デフォルトドライバー | Selenium + Chrome がデフォルト | driven_by未指定時 |
| BR-24-02 | デフォルト画面サイズ | 1400x1400 ピクセル | screen_size未指定時 |
| BR-24-03 | 失敗時スクリーンショット | テスト失敗時に自動撮影 | rack_test以外のドライバー |
| BR-24-04 | ヘッドレスモード | headless_chrome/headless_firefoxで画面なし実行 | CI環境等 |

### 計算ロジック

スクリーンショットファイル名：
```ruby
# 失敗時: failures_{test_method_name}.png
# 成功時: {sequential_number}_{test_method_name}.png
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| setup | テスト用テーブル | TRUNCATE/INSERT | テストフィクスチャのロード |
| teardown | テスト用テーブル | ROLLBACK/TRUNCATE | テストデータのクリーンアップ |

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

システムテストはトランザクショナルフィクスチャを使用しない（別スレッドでサーバーが動作するため）。DatabaseCleanerなどのgemでテスト間のデータ分離を行う。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Selenium::WebDriver::Error::WebDriverError | DriverError | ブラウザドライバー未インストール | chromedriver/geckodriver をインストール |
| Capybara::ElementNotFound | AssertionError | 要素が見つからない | セレクタを確認、wait時間を調整 |
| Net::ReadTimeout | TimeoutError | ページ読み込みタイムアウト | Capybara.default_max_wait_timeを調整 |

### リトライ仕様

Capybaraはデフォルトで要素検索を自動リトライする（default_max_wait_time秒間）。

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

システムテストでは、テストサーバーが別スレッドで動作するため、トランザクショナルフィクスチャは使用できない。テスト間のデータ分離はTRUNCATEまたはDatabaseCleanerで行う。

## パフォーマンス要件

- ヘッドレスモードはGUIモードより高速
- 大量のテストケースはCI/CDで並列実行を推奨
- Capybara.default_max_wait_time のデフォルトは2秒

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

- テスト環境専用のデータベースを使用すること
- 本番環境のクレデンシャルをテストコードに含めないこと
- スクリーンショットに機密情報が含まれる場合はCI成果物から除外

## 備考

- Capybara 3.26以上が必要
- Selenium WebDriver 4.0以上が必要
- ヘッドレスChromeが最も一般的なCI環境向けドライバー

---

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

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

### 推奨読解順序

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

システムテストの基底クラスを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | system_test_case.rb | `actionpack/lib/action_dispatch/system_test_case.rb` | SystemTestCaseクラス、Capybara DSLのinclude、driven_byメソッド |

**読解のコツ**: SystemTestCaseがCapybara::DSLとCapybara::Minitest::Assertionsをincludeしている点に注目。

**主要処理フロー**:
- **114-118行目**: CapybaraのDSLとアサーションをinclude
- **122-126行目**: initialize でドライバーを使用開始
- **128-136行目**: start_application でCapybara.appを設定
- **158-162行目**: driven_by でドライバー設定

#### Step 2: ドライバー設定を理解する

ブラウザドライバーの登録と設定を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | driver.rb | `actionpack/lib/action_dispatch/system_testing/driver.rb` | Driverクラス、各ドライバーの登録方法 |

**主要処理フロー**:
- **10-25行目**: initialize でドライバータイプに応じた初期化
- **27-31行目**: use メソッドでドライバーを登録・設定
- **38-48行目**: register メソッドでCapybaraにドライバーを登録
- **55-58行目**: register_selenium でSeleniumドライバー登録

#### Step 3: スクリーンショット機能を理解する

テスト失敗時のスクリーンショット撮影機能を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | screenshot_helper.rb | `actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb` | take_screenshot、take_failed_screenshot メソッド |

**主要処理フロー**:
- **41-48行目**: take_screenshot でスクリーンショット撮影
- **53-58行目**: take_failed_screenshot で失敗時のみ撮影
- **115-117行目**: save_image でCapybaraの save_screenshot を呼び出し

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

```
ApplicationSystemTestCase (継承クラス)
    │
    ├─ ActionDispatch::SystemTestCase
    │      │
    │      ├─ include Capybara::DSL (115行目)
    │      │      └─ visit, click_on, fill_in 等
    │      │
    │      ├─ include Capybara::Minitest::Assertions (116行目)
    │      │      └─ assert_text, assert_selector 等
    │      │
    │      ├─ driven_by (158行目)
    │      │      └─ SystemTesting::Driver.new (161行目)
    │      │             │
    │      │             ├─ register (38行目)
    │      │             │      └─ Capybara.register_driver
    │      │             │
    │      │             └─ setup (80-82行目)
    │      │                    └─ Capybara.current_driver =
    │      │
    │      └─ start_application (128行目)
    │             └─ Capybara.app = Rack::Builder.new
    │
    └─ ScreenshotHelper
           │
           ├─ take_failed_screenshot (53行目)
           │      └─ take_screenshot (56行目)
           │             │
           │             ├─ save_image (115-117行目)
           │             │      └─ page.save_screenshot
           │             │
           │             └─ display_image (134-148行目)
           │
           └─ failed? (154-156行目)
```

### データフロー図

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

テストコード ───▶ SystemTestCase ───▶ テスト結果
      │                    │
      │                    ▼
driven_by設定 ───▶ Driver初期化 ───▶ Capybaraドライバー登録
      │                    │
      │                    ▼
Railsアプリ ───▶ テストサーバー起動 ───▶ localhost:port
      │                    │
      │                    ▼
Capybara DSL ───▶ ブラウザ操作 ───▶ ブラウザ画面
      │                    │
      │                    ▼
      │              ┌─────────────────┐
      │              │ スクリーンショット │───▶ tmp/screenshots/*.png
      │              │ (失敗時)         │
      │              └─────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| system_test_case.rb | `actionpack/lib/action_dispatch/system_test_case.rb` | ソース | SystemTestCase基底クラス |
| driver.rb | `actionpack/lib/action_dispatch/system_testing/driver.rb` | ソース | ドライバー登録・設定 |
| browser.rb | `actionpack/lib/action_dispatch/system_testing/browser.rb` | ソース | ブラウザ設定 |
| server.rb | `actionpack/lib/action_dispatch/system_testing/server.rb` | ソース | テストサーバー設定 |
| screenshot_helper.rb | `actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb` | ソース | スクリーンショット撮影 |
| setup_and_teardown.rb | `actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb` | ソース | テストのセットアップ・ティアダウン |
| system_test_helper.rb | `actiontext/lib/action_text/system_test_helper.rb` | ソース | ActionText用システムテストヘルパー |
