Given-When-Then(GWT)形式
1. 目的
要求仕様におけるシナリオの構造化
- 要件仕様やテストシナリオを誰でも理解できる統一された構造で記述する
- エンジニア/QA/ビジネス担当者などの異なる立場のメンバー間で認識のズレを無くし、共通言語として機能させる
2. 課題
事前条件や期待値に対する認識が一致しない
- Given-When-Then形式のような構造化されたフォーマットが無い場合、テスト条件や期待結果が人によって書き方がバラバラになり、レビューや引き継ぎが困難
- そのような状況では要件定義が曖昧なまま実装に進むことになり、手戻りの発生確率が上昇する
- また、エンジニア以外のメンバーがテスト内容を把握できず、他のメンバーが品質保証に関与することも困難
- テストの前提条件・操作・結果が曖昧なまま進行し、それらの条件の抜け漏れに気づきにくいので、品質保証の精度も低下
3. 解決策
Given/When/Thenでシナリオを構造化する
- (1) Given(前提)
- (2) When(操作)
- (3) Then(結果)
例1: シンプルなシナリオ
- Given: ユーザーがログイン済みである
- When: 「退会する」ボタンを押し、確認ダイアログで「OK」を選択する
- Then: アカウントが削除され、トップページへリダイレクトされる
例2: And/Butを使用した複数条件を持つシナリオ
- Given:
- ユーザーがログイン済みである
- And: カートに商品が1件以上入っている
- When:
- Then:
- 注文確認画面が表示される
- And: カートの中身が空になる
- But: お気に入りリストは変化しない
例3: 異常系パターン
- Given:
- When:
- Then:
- 「パスワードが正しくありません」というエラーメッセージが表示される
- And: ページ遷移は起きない
4. メリット
高い可読性
- Given/When/Thenというコンパクトな構造で表現される為、誰でも理解できる
- エンジニアだけでなく非エンジニアでもシナリオを理解/レビューすることが可能
抜け漏れの防止
- 前提/操作/結果を分離することで観点が整理される為、抜け漏れを防ぐことができる
自動テストとの親和性
- 多くのBDDツールでもテストシナリオをGiven/When/Thenで構成する
- したがって、テストシナリオをBDDツールのテストケースに直接変換する事ができる
ドキュメントとテストの二重管理が不要
- シナリオがそのまま仕様書になるのでドキュメントとテストシナリオの二重管理の必要がなくなる
チーム間の共通言語になる
- 開発/QA/PO間の認識齟齬を減らすことが期待できる
5. デメリット
記述コストがかかる
- 当然だがこれまで書いていなかった場合、記述コストが増加する
- また、全シナリオをGWT形式で書くと更に工数が増える
- プロダクトにとってクリティカルなケースに絞って書くなどの選別も必要
細かいロジックの表現が苦手
- 複雑な分岐や数値計算の検証には不向きな場合がある
- 複数の入力値パターンを検証したい場合は、Scenario Outline(シナリオアウトライン)+Examples テーブルを使うのがよい
- 詳細は
Appendix-1参照のこと
形骸化しやすい
- 形式だけ整えて中身が曖昧なシナリオになりがち
- 悪例:
Given: ユーザーが操作する
When: いろいろ操作する
Then: うまくいく
- ↑では具体的に何がどうなるのかまるで分からない
- 形骸化を防ぐには、Given・When・Then それぞれが「前提/操作/観測可能な結果」になっているかチェックする
ツール導入のハードルがある
- BDDフレームワークを使う場合、学習コストが発生する
6. 注意事項
Then は観測可能な結果のみ書く
- 内部処理(「DBに保存される」等)ではなく、外側から確認できる振る舞いを記述する
1シナリオにつき1つのWhenを原則とする
Given の前提は最小限に絞る
And/But を活用する
- 条件や結果が複数ある場合は
And で繋ぐと読みやすくなる
実装の詳細を書かない
- UIの具体的な操作手順より「何をしたか」という意図を記述する
参考資料
Appendix-1 細かいロジックの確認が伴う場合の解決策
- 複数の入力値パターンを検証したい場合は、Scenario Outline + Examples テーブルを使うと、GWT形式を保ちながら網羅的なテストを書くことができる
- 例:
Scenario Outline: ログイン試行
Given: ユーザーが <email> と <password> を入力する
When: ログインボタンを押す
Then: <result> が表示される
Examples:
| email | password | result |
| [email protected]| correct | ダッシュボード |
| [email protected]| wrong | エラーメッセージ |
- Examplesのテーブルの値がemail/password/resultの設定値となる