概要
- EARS(Easy Approach to Requirements Syntax)は、要求仕様を構造化して記述するための記法です
- 生成AIと組み合わせることで、以下が効率的に実現できます:
- 曖昧さのない要求定義
- テスト可能な仕様の作成
- テストコードへの自動変換
ポイント
- EARS記法: 「WHEN [条件] THE SYSTEM SHALL [期待される動作]」の形式で記述
- テスト可能な要件:曖昧さを排除し、検証可能な形で記述
- テストコードの作成に転用できる
- 完全性:すべての条件と振る舞いを網羅
EARSの5つの要求タイプ
-
Ubiquitous(常時): システムが常に満たすべき要求
- 例:「システムはパスワードを平文で保存してはならない」
-
Event-driven(イベント駆動): 特定の条件で発動する要求
- 例:「ユーザーがログインボタンをクリックしたとき、システムは...」
-
State-driven(状態駆動): 特定の状態における要求
- 例:「ユーザーが未認証の状態にあるとき、システムは...」
-
Unwanted behavior(望まない挙動): システムが回避すべき状況
- 例:「システムは...してはならない」
-
Optional feature(オプション機能): ユーザーが選択できる機能
- 例:「ユーザーが選択した場合、システムは...」
作成順序とタイミング
- 要求を把握
- ざっくりEARS作成(生成AI)
- EARS詳細化(途中で気づいた要求を追加)
- EARS最終レビュー
生成AI活用時の注意点
EARS生成プロンプト例
以下の機能について、EARS形式で要求仕様を書いてください。
実装方法や技術選定には触れず、「何を満たすべきか」のみ記述してください。
【機能】
認証機能
【制約】
- セッションタイムアウト: 30分
- アカウントロック: 5回失敗で15分間
【出力形式】
- 要求タイプごとにグルーピング(Ubiquitous/Event-driven/State-driven/Unwanted/Optional)
- 各要求に一意のID(REQ-XXX-U001形式)
- 検証可能な形で記述
EARSからテストケースへの変換
EARSで書かれた要求は、テストケースに変換できます。
また、EARSファイルとテストコードを相互に参照することで、要求とテストの対応関係を明確にできます。
変換例
Ubiquitous(常時要求)→ Invariant Test
システムが常に満たすべき条件を検証
# EARS
REQ-AUTH-U001: システムはパスワードを平文で保存してはならない
# テストケース
- パスワードがハッシュ化されて保存されること
- データベースに平文パスワードが存在しないこと
Event-driven(イベント駆動要求)→ Scenario Test
特定の条件下での動作を検証
# EARS
REQ-AUTH-E002: 10回連続でログインに失敗したとき、
システムはそのアカウントを15分間ロックする
# テストケース
正常系:
- 10回連続失敗後、アカウントがロックされること
- ロックから15分後、再度ログイン可能になること
境界値:
- 9回連続失敗では、まだログイン試行できること
- 10回目の失敗直後にロックされること
テストコード生成プロンプト例
以下のEARS要求から、[テストフレームワーク]のテストコードを生成してください。
【EARS要求】
REQ-AUTH-E002: 10回連続でログインに失敗したとき、
システムはそのアカウントを15分間ロックする
【テストフレームワーク】
Laravel 11 + PHPUnit
【注意事項】
- 正常系、異常系、境界値をカバーすること
- (テストコード例、スタイルの指定)
EARSテンプレート
# EARSテンプレート
EARS (Easy Approach to Requirements Syntax) で要求仕様を作成する際のテンプレートです。
## ファイル命名規則
- **ファイル名**: `EARS-XXX-[機能名].md`
- **番号**: 001から開始の3桁連番(例:EARS-001、EARS-002)
- **機能名**: kebab-case(ハイフン区切り)で記載
例:
- `EARS-001-auth.md`
- `EARS-002-file-upload.md`
- `EARS-003-notification.md`
## EARS更新時の方針
**基本**: EARSは上書きで最新状態を保ちます。
- 軽微な修正: 直接上書き(Gitで履歴追跡)
- 重大な変更: 新しいEARSファイルを作成し、古いファイルのStatusをDeprecatedに変更
### 既存EARSとの関係性の表現
- `Supersedes EARS-001`: EARS-001を完全に置き換える
- `Amends EARS-003`: EARS-003を部分的に修正・拡張する
## フォーマット
```markdown
# EARS-XXX: [機能名]
**Status:** [Draft | Active | Deprecated | Superseded by EARS-XXX]
**Date:** YYYY-MM-DD
**Related ADR:** ADR-XXX(該当する場合)
## Ubiquitous requirements(常時要求)
システムが常に満たすべき要求
1. REQ-U001: システムは...
1. REQ-U002: システムは...
## Event-driven requirements(イベント駆動要求)
特定の条件で発動する要求
1. REQ-E001: [トリガー]のとき、システムは...
1. REQ-E002: [トリガー]のとき、システムは...
## State-driven requirements(状態駆動要求)
特定の状態における要求
1. REQ-S001: [状態]にあるとき、システムは...
1. REQ-S002: [状態]にあるとき、システムは...
## Unwanted behaviors(望まない挙動)
システムが回避すべき状況
1. REQ-W001: システムは...[してはならない]
1. REQ-W002: システムは...[してはならない]
## Optional features(オプション機能)
ユーザーが選択できる機能
1. REQ-O001: ユーザーが選択した場合、システムは...
1. REQ-O002: ユーザーが選択した場合、システムは...
## Links: 参考リンク
- [関連ドキュメント](URL)
- [仕様書](URL)
```
## 使用方法
1. EARS番号(EARS-XXX)は連番で管理
2. 機能ごとにEARSファイルを作成
3. 要求IDはファイル内で一意に(REQ-[タイプ][連番])
4. 各要求は具体的で検証可能な形で記載
## 要求IDの命名規則
`REQ-[タイプ][連番]`
- **タイプ**: U(Ubiquitous)、E(Event-driven)、S(State-driven)、W(Unwanted)、O(Optional)
- **連番**: 001から開始の3桁
- **ファイル名で機能を識別**するため、要求ID内に機能名は不要
例:
- `EARS-001-auth.md` 内の `REQ-U001`: 認証機能の常時要求
- `EARS-002-file-upload.md` 内の `REQ-E001`: ファイルアップロード機能のイベント駆動要求
## テストコード生成時の指示例
```
「EARS-XXX-[機能名].mdを参照して、[言語/フレームワーク]のテストコードを生成してください」
例:
- 「EARS-001-auth.mdを参照して、PHPUnit Feature Testを生成してください」
- 「EARS-001-auth.mdを参照して、Vitest(TypeScript)のテストを生成してください」
```
## 参考リンク
- [EARS公式サイト](https://alistairmavin.com/ears/)
EARSかADRか
EARSとADR(Architectural Decision Record)はシステムの根本的な部分を定める点において似ています。
基本的な考え方の違いは、EARSはシステムが「できること」、ADRは「何故」です。
| 観点 | EARS | ADR |
|---|---|---|
| 問い | 「何を満たすべきか?」 | 「何故そう決めたか?」 |
| 焦点 | 要求・制約 | 意思決定・トレードオフ |
| 時制 | 現在形(〜である) | 過去形(〜を選択した) |
| 変更 | 要求変更時に更新 (重要なものは変更履歴を記載) |
不変(新しいADRで上書き) |
| 検証 | テスト可能 | 説明責任 |
| 内容 | EARS | ADR |
|---|---|---|
| ユーザーができること | ✅ | ❌ |
| システムが保証すること | ✅ | ❌ |
| パフォーマンス数値 | ✅ | ❌ |
| セキュリティ制約 | ✅ | ❌ |
| 使用する技術・ライブラリ | ❌ | ✅ |
| 技術選定の理由 | ❌ | ✅ |
| トレードオフ | ❌ | ✅ |
| 不採用案 | ❌ | ✅ |
| アーキテクチャ決定 | ❌ | ✅ |