# テスト方針書

## 概要

本ドキュメントは、Symfony 8.1 フレームワーク（モノリポジトリ構成）におけるテスト方針を定義する。Symfony は Bridge / Bundle / Component の3層から構成される大規模 PHP フレームワークであり、各パッケージが独立した phpunit.xml.dist を持ち、コンポーネント単位でのテスト実行を基本とする。GitHub Actions を CI/CD 基盤として活用し、複数 PHP バージョン・複数 OS・複数依存パターンでの品質保証を実現する。

## テスト戦略

### テストレベル

| レベル | 目的 | 担当 |
| --- | --- | --- |
| 単体テスト | 各コンポーネント・クラス単位の機能検証。PHPUnit を用いて各パッケージの Tests/ ディレクトリ配下で実行する | 各コンポーネント開発者 |
| 結合テスト | 外部サービス（Redis, PostgreSQL, MongoDB, RabbitMQ, Memcached, LDAP, Kafka, Couchbase, AWS LocalStack 等）との統合動作を検証する。`--group integration` で実行される | CI/CD パイプライン（integration-tests.yml） |
| システムテスト | Windows 環境での動作確認、TTY テスト、SIGCHLD 対応テスト、FrankenPHP との連携テストなど、プラットフォーム固有の動作を検証する | CI/CD パイプライン（windows.yml, unit-tests.yml 内の特殊ステップ） |
| 受入テスト | Intl/Emoji データの正当性検証、PHPUnit Bridge の後方互換性確認（PHPUnit 9.6 でのテスト）、パッケージメタデータの検証を行う | CI/CD パイプライン（intl-data-tests.yml, package-tests.yml） |

### テスト種別

| 種別 | 概要 | 実施タイミング |
| --- | --- | --- |
| 機能テスト | 各コンポーネントの機能正当性を PHPUnit で検証。`benchmark`, `intl-data`, `integration`, `transient` グループを除外した通常テストスイート | push / pull_request 時に自動実行 |
| 静的解析 | Psalm（errorLevel 5）による型安全性検証、PHP-CS-Fixer によるコーディングスタイル検証、Twig CS Fixer による Twig テンプレートの lint | pull_request 時に自動実行 |
| 性能テスト | `benchmark` グループとして定義。通常の CI 実行からは除外されており、必要に応じて手動実行する | 必要に応じて手動実行 |
| セキュリティテスト | OpenSSF Scorecard による supply-chain セキュリティ分析。8.1 ブランチへの push 時および週次スケジュールで実行 | push（8.1 ブランチ）/ 週次スケジュール（毎週土曜 4:34 UTC） |
| 互換性テスト | PHP 8.4 / 8.5 / 8.6 の複数バージョンでのテスト実行、high-deps / low-deps モードでの依存関係互換性検証 | push / pull_request 時に自動実行 |
| クロスプラットフォームテスト | Windows（x86）環境での最小拡張構成・全拡張構成でのテスト実行 | push / pull_request 時に自動実行 |

## テスト環境

| 環境 | 用途 | 構成 |
| --- | --- | --- |
| Ubuntu 24.04（GitHub Actions） | 単体テスト・結合テスト・静的解析の主要実行環境 | PHP 8.4 / 8.5 / 8.6、拡張: amqp, apcu, brotli, igbinary, intl, mbstring, memcached, redis, relay, zstd |
| Windows 2022（GitHub Actions） | クロスプラットフォーム互換性検証 | PHP 8.4（x86）、最小拡張構成（xsl, mbstring, openssl, curl）および全拡張構成（+ apcu, igbinary, intl, redis, sodium, opcache, fileinfo, pdo_sqlite） |
| 結合テスト用サービス群（Docker） | 外部サービスとの統合テスト | PostgreSQL 16, Redis 6.2.8（単体・認証付・クラスター・Sentinel・レプリケーション）, Memcached 1.6.5, RabbitMQ 3.8.3, MongoDB, Couchbase 6.5.1, LocalStack 3.0.2（AWS）, Kafka 3.7, Zookeeper, OpenLDAP, FTP, FrankenPHP 1.1.0, pgbouncer |
| ローカル開発環境 | 開発者による手元テスト実行 | `./phpunit` ラッパースクリプトを使用。`phpunit.xml.dist` をプロジェクトルートに配置 |

## テストツール

| ツール | 用途 | バージョン |
| --- | --- | --- |
| PHPUnit | 単体テスト・結合テストの実行フレームワーク | 11.3 以上（phpunit.xml.dist の schema に基づく） |
| Symfony PHPUnit Bridge | PHPUnit の拡張。クロックモック、非推奨検出、テストヘルパー機能を提供 | 7.4 以上 / 8.0 以上（composer.json require-dev） |
| Psalm | 静的型解析 | phar 版 @stable（CI で動的インストール） |
| PHP-CS-Fixer | コーディングスタイル検証・自動修正 | @Symfony / @Symfony:risky ルールセット適用 |
| Twig CS Fixer | Twig テンプレートの lint | ^3.9.0 |
| Fabbot | PR 上でのコーディング規約チェック（symfony-tools/fabbot） | main ブランチ（外部ワークフロー参照） |
| OpenSSF Scorecard | supply-chain セキュリティ分析 | v2.4.1 |
| GNU parallel | テストの並列実行（コンポーネント単位で並列化） | OS パッケージ |

## カバレッジ目標

| 対象 | 目標値 |
| --- | --- |
| 行カバレッジ | 明示的な数値目標は設定されていない（注: CI では `coverage: "none"` が設定されており、カバレッジ計測は通常の CI 実行では無効化されている） |
| 分岐カバレッジ | 明示的な数値目標は設定されていない |

補足: Symfony プロジェクトでは、カバレッジの数値目標よりも、以下の品質ゲートを重視する方針を採用している。

- `failOnDeprecation="true"`: 非推奨警告が発生した場合テスト失敗
- `failOnRisky="true"`: リスキーテストが検出された場合テスト失敗
- `failOnWarning="true"`: 警告が発生した場合テスト失敗
- `zend.assertions=1`: アサーションを有効化した状態でのテスト実行
- `error_reporting=-1`: 全てのエラー・警告を検出対象

## テストデータ

テストデータの準備は以下の方針に従う。

1. **Fixtures ディレクトリ**: 各コンポーネントの `Tests/Fixtures/` ディレクトリにテスト用データファイル（PHP, JSON, YAML, XML, HTML 等）を配置する
2. **LDAP フィクスチャ**: `src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif` に LDAP テスト用の LDIF データを保持し、CI の結合テスト時に OpenLDAP コンテナへロードする
3. **FTP フィクスチャ**: CI 環境で `ftpusers/test/pub/` にテスト用ファイルを動的生成する
4. **pgbouncer 設定**: `src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Fixtures/pgbouncer/` に pgbouncer の設定ファイル・認証ファイルを配置
5. **Intl/Emoji データ**: `src/Symfony/Component/Intl/Resources/data/` および `src/Symfony/Component/Emoji/Resources/data/` にリソースデータを保持し、圧縮前後の両方でテストを実行する
6. **HTTP テスト用フィクスチャ**: `src/Symfony/Component/HttpClient/Tests/Fixtures/response-functional/` および `src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/` に FrankenPHP 経由で配信するレスポンスフィクスチャを配置
7. **環境変数フィクスチャ**: `TEST_GENERATE_FIXTURES=0` により、通常テスト時にフィクスチャの再生成を抑止する

## 不具合管理

不具合管理は以下の方法で実施する。

1. **GitHub Issues**: 不具合の報告・追跡は GitHub Issues を使用する
2. **GitHub Pull Requests**: 修正は PR を通じて行い、CI による自動テスト通過を必須とする
3. **非推奨管理**: `SYMFONY_DEPRECATIONS_HELPER` 環境変数で非推奨の取扱いを制御する。low-deps モードでは `weak` に設定し、それ以外では strict モード（デフォルト）で運用する
4. **Psalm ベースライン**: `.github/psalm/psalm.baseline.xml` に既知の静的解析警告をベースラインとして管理し、新規警告のみを検出対象とする
5. **テストグループによる分類**:
   - `benchmark`: パフォーマンスベンチマーク（通常 CI から除外）
   - `intl-data`: 国際化データテスト（専用ワークフローで実行）
   - `integration`: 結合テスト（専用ワークフローで実行）
   - `transient`: 一時的な失敗が許容されるテスト（通常 CI から除外）
   - `transient-on-windows`: Windows 環境で一時的な失敗が許容されるテスト
   - `tty`: TTY 依存テスト（script コマンド経由で別途実行）
   - `legacy`: レガシーテスト（high-deps + x.4 ブランチで除外）

## CI/CD連携

### GitHub Actions ワークフロー一覧

| ワークフロー | トリガー | 目的 |
| --- | --- | --- |
| Unit Tests（unit-tests.yml） | push / pull_request | PHP 8.4 / 8.5 / 8.6 での単体テスト実行。high-deps / low-deps / default の3モード |
| Integration（integration-tests.yml） | push / pull_request | 外部サービス連携の結合テスト実行。Docker サービスコンテナを使用 |
| Windows（windows.yml） | push / pull_request | Windows x86 環境での互換性テスト。最小拡張・全拡張の2構成 |
| Intl/Emoji data（intl-data-tests.yml） | push / pull_request（対象パス限定） | 国際化・絵文字データの正当性検証。圧縮データでのテストを含む |
| Verify Packages（package-tests.yml） | pull_request（src/** 変更時） | パッケージメタデータ（LICENSE, CHANGELOG.md, README.md 等）の存在・整合性検証 |
| Psalm（psalm.yml） | pull_request | Psalm による静的型解析。ベースライン差分での新規警告検出 |
| Lint PhpUnitBridge（phpunit-bridge.yml） | push / pull_request（Bridge/PhpUnit/** 変更時） | PHPUnit Bridge の PHP lint 検証 |
| CS / Fabbot（fabbot.yml） | pull_request | コーディングスタイルの検証 |
| Twig CS Fixer（twig-cs-fixer.yml） | push / pull_request（**.twig 変更時） | Twig テンプレートの lint |
| Scorecards（scorecards.yml） | push（8.1 ブランチ）/ 週次スケジュール / branch_protection_rule | OpenSSF Scorecard による supply-chain セキュリティ分析 |

### 実行戦略

- **並列実行**: GNU parallel を使用し、コンポーネント単位でテストを並列実行（`parallel -j +3`）
- **並行性制御**: `concurrency` 設定により、同一ワークフロー・同一ブランチの重複実行を防止（`cancel-in-progress: true`）
- **マトリクス戦略**: PHP バージョン（8.4, 8.5, 8.6）と依存モード（high-deps, low-deps, default）の組み合わせで実行（`fail-fast: false`）
- **パッチテスト**: `build-packages.php` スクリプトにより、変更されたコンポーネントのローカルパッケージを作成し、他コンポーネントからの参照テストを実施
- **クロスバージョンテスト**: high-deps モードでは、直前のメジャーバージョン（7.4 LTS）をチェックアウトしてパッチ済みコンポーネントとの互換性を検証

## 備考

1. **PHPUnit ラッパースクリプト**: プロジェクトルートの `phpunit` スクリプトが PHPUnit のインストールおよび実行を管理する。`./phpunit install` でインストール、`./phpunit <args>` でテスト実行を行う
2. **Symfony PHPUnit Bridge の拡張機能**: `SymfonyExtension` を PHPUnit 拡張として登録し、クロックモック（Cache, Console, HttpFoundation, Uid 等の名前空間に対応）を提供する
3. **PHP 要件**: PHP >= 8.4 が必須（composer.json の require に基づく）
4. **各パッケージの独立性**: 各コンポーネント・ブリッジ・バンドルは独自の `phpunit.xml.dist` を持ち、単独でのテスト実行が可能。メインの `phpunit.xml.dist` は全パッケージを統合したテストスイートを定義する
5. **メモリ制限**: テスト実行時は `memory_limit=-1`（無制限）に設定
6. **ソケットタイムアウト**: `default_socket_timeout=10` を設定し、外部接続のハングアップを防止
7. **テスト用 PHP 拡張**: couchbase, memcached, mongodb, redis, rdkafka, xsl, ldap, relay 等の拡張を結合テスト環境で使用
8. **Composer Flex**: 単体テスト環境で Composer Flex ツールを活用し、Symfony バージョン要件の制御を行う
