BDDについて ~ソフトウェアの振る舞いに焦点を当て、要件を明確にし、コミュニケーションを改善~
はじめまして、QAエンジニアの田中です。今回はアジャイル開発手法の一つのBDDについてご紹介したいと思います。
目次
BDDとは何か?
BDD(Behavior-Driven Development)は、ビヘイビア駆動開発や振る舞い駆動開発とも呼ばれ、テスト駆動開発から派生したものです。ソフトウェアの振る舞いや機能を重視して、品質と要件の向上をめざします。具体的には、ソフトウェアの振る舞いを明確に定義することで、プログラム開発とテストを効率化することができます。
まず初めに、自動販売機の例を通して、BDDを説明していきます。自動販売機では、お客さんがお金を投入し飲み物を購入できます。BDDの視点から、具体的な振る舞いのシナリオを考えてみましょう。
- シナリオ1: お客さんがお金を投入して自動販売機で飲み物を購入しようとする
- もし、お客さんが自動販売機にお金を投入し、飲み物の選択ボタンをクリックしたら、選択ボタンに応じた飲み物が出てくるべきです。
- そして、おつりが必要な場合、自動販売機は、必要な金額をおつりとして、お客さんに出すべきです。
- シナリオ2: お客さんがお金を投入しないで自動販売機で飲み物を購入しようとする
- もし、お客さんが自動販売機にお金を投入せずに、飲み物の選択ボタンをクリックしたら、飲み物が出てくるべきではないです。
このシナリオは、ビジネスの視点からソフトウェアの振る舞いを記述したものであり、BDDはこのようなシナリオを通じてソフトウェアの開発とテストを導く手法です。鍵となるポイントは、ビジネス要件とソフトウェアの振る舞いを結びつけ、それに基づいてテストを設計し、ソフトウェアを開発することです。
この自動販売機の例から、BDDが開発プロセスを明確にし、チームが顧客の要件を正確に理解するのに役立つことがわかります。これにより、顧客の期待に応える高品質なソフトウェアを迅速に提供することが可能になります。
BDDについて更に詳しく知りたい方は、Sqriptsでスクリプターのブロッコリーさんが詳しい記事を書いておりますので、そちらを参照願います。
■【連載】TDDの派生形!BDDやATDDとは何か? 概念からプロセスまで徹底解説!|Sqripts
スクリプター:風間裕也(ブロッコリー)
BDDの特徴・メリット
BDDの特徴やメリットには、下記のようなものがあります。
- 振る舞いに焦点を当てる
開発者、テスター、ビジネスステークホルダーが共通の理解を持つために、振る舞いに対する要件や期待値を明確に定義します。非開発者と開発者間の認識齟齬の低減が期待でき、プロジェクトの効率を向上させます。 - 自然言語で記述
テストのシナリオ(テストケース)において振る舞いや要件を自然言語で記述します。シナリオは様々なフェーズのテストで柔軟に活用でき、開発者が書く自動テスト(ユニットテスト、インテグレーションテストなど)などの開発者テストでも適用可能です。非技術者も理解しやすく、コミュニケーションの質を向上させます。日本語で書かれたテストシナリオがそのまま実行でき、異なるパラメータの入力も日本語で記述されたシナリオ内で表現できます。一般的な文法は「Given-When-Then」で表現され、前提条件(Given)、アクション(When)、結果(Then)を記述します。非開発者による振る舞いや要件の記述(シナリオ作成)が期待できます。後ほど、例を用いて説明します。 - テストケースとしてのBDD
BDDはテストケース(シナリオ)を自動化するための方法としても使用されます。BDDフレームワークを使用して自動テストケースを記述し、実行することで、振る舞いに関する問題を特定し、外部品質を確保します。また、リファクタリングなどの内部実装変更に対して、テストケースが影響を受けないため、テストケースのメンテナンスが減ります。 - テストファースト・シフトレフト
BDDは、テストファースト・シフトレフトの原則に基づいています。コードを書く前に振る舞いや要件を明確にし、それに基づいてシナリオを記述します。その後、それに合格するプロダクトコードを書いていきます。これにより、テスタビリティの高い、かつ疎結合なコードが作成されることにより、各部分が独立してテストでき、特定の変更が他の部分に影響を与えにくくなるため、コードの品質向上とバグの早期発見を実現できます。早い段階で問題点をフィードバックすることで、大きな手戻りや未然にバグを防ぐことが可能で、全体のテスト時間を短縮し、コスト低減も期待できます。
QAエンジニアからみたBDDのメリット
では、QAエンジニアからみたBDDのメリットには、どのようなものがあるでしょう?BDDを導入することで、QA(品質保証)の観点からは、次のようなメリットがあります。
- 開発者とQAエンジニアの共通理解の促進
開発者とQAエンジニアの連携が強化されます。開発者とQAエンジニアが共通のBDDの仕様や振る舞い定義に基づいて作業を行うため、コミュニケーションや理解が容易になります。 - QAエンジニアによるテストのレビュー・作成が可能
QAエンジニアは開発者テスト段階からテストのレビュー・作成を行えるようになります。BDDの仕様に基づいてシナリオを作成し、テストの品質を向上させることができます。
つまり、BDDを導入することで、品質保証プロセスにおいて開発者とQAエンジニアの連携が強化され、テストの品質向上を実現することができます。
BDDの進め方
では、BDDの進め方について、ブロッコリーさんの記事の例を参考に、見てみましょう。
まず、「#1 ユーザーストーリーを選ぶ」では、システムにおいて実装すべき機能を引き出し、優先順位を付けて行きます。 次に「#2 要件ワークショップ」では、優先順位を付けられた機能に対して、振る舞いの実例を基に詳細な要件を探索し、明確になっていなかった要件を発見していきます。
次に、実例をシナリオに変換する「#3 定式化」を行います。ここでは、振る舞い定義に基づいたシナリオが自然言語(Gherkin※1記法など)で記載されているため、開発者はもちろんQAエンジニアにもシナリオの理解が深まり、開発者テスト段階からテストのレビュー・作成を行うことが可能です。これにより、開発の早い段階からQAエンジニアが参画してテストを行うことができるため、テストの品質向上につながります。
Feature: 自動販売機 Scenario: 飲み物を買うと、飲み物代を引いた金額のお釣りが出る Given 自動販売機がある When 550 円を入れる And 120 円の "コーラ" を選択する Then "コーラ" が出てくる And 430 円が出てくる
「#4 レビュー」では、他のチームメンバーからの視点を取り入れることで、潜在的な問題を特定し、誤解や不足を解消し、ソフトウェアの品質を高めます。「#5 自動化」では、BDDのフレームワークを導入により自動テストのコードを書きます。自動化についての詳細については、下記を参考にしてください。
参考:TDDとBDD/ATDD(7) BDDのプロセスその3「自動化(Automation)」
スクリプター:風間裕也(ブロッコリー)
次に下記の3つのサイクルを回し、コードを「#6 実装」していきます。
- Red:プログラマーがテストを書く
- Green:テストが成功するのに十分なコードを書く
- Refactor:コードを整理する
テストコードをシナリオに合わせて作成し、それをパスするコードを実装、このプロセスを繰り返します。「#7 補足的なテスト」では、自動テストを補う形で、探索的テスト、侵入テストや負荷テストを行い、ソフトの品質を高めていきます。最後に、出荷可能なインクリメントを生成「#8 リリース」して、次の開発につなげます。
事例(PoCをやってみた)
BDDを導入することで、QAプロセスにおいて開発者とQAエンジニアの連携が強化され、テストの品質向上を実現できることが明らかです。しかし、理論的なメリットを持つ取り組みが実際の現場でどのように機能するかは、常に疑問が残ります。
そのため、想定しているQA目線でのメリットが実際に享受できるかをPoCで確認してみることにしました。
PoC事例詳細
プロジェクトの品質向上を目指し、テストに関する課題を解決するために、BDDの導入による品質向上の具体的な効果を実証し、その実現可能性を探ってみました。
難しい要件があるプロジェクトで、下記のようないくつかの課題を抱えており、品質を十分に担保できるかに懸念を抱いていました。
- 開発者によるテストに十分な時間が確保されていない
- 開発者だけでテストケースを作成しているため、テストケースを過不足なく洗い出せるか不安
- 開発者によるアサーション(テストの条件や期待結果)の設定が難しい
そこで、BDDを取り入れて、上記の改善を図ることを目指すPoCを実施しました。実際に行った手順は、下記の通りです。(今回のPoCでは、BDDの進め方の「#2 要件ワークショップ」から「#6 実装」のプロセスを実施しています。)
- 実例を基にした要件整理とテストケース作成
開発者とQAエンジニアは、実際の実例を基に詳細な要件を整理し、ビジネス要件を明確にしました。その後、QAエンジニアはGherkin記法を用いて、テストケースを記述しました。これは、BDDの進め方の「#2 要件ワークショップ」「#3 定式化」に該当します。 - テストケースの合同レビュー
開発者とQAエンジニアはテストケースについて「#4 レビュー」を行い、テストケースを明確化しました。 - テストコード実装
開発者は、テストケースを基にテストコードを実装していきます。これは、BDDの進め方の「#5 自動化」に該当します。
今回のテスト自動化環境では、テストのフレームワークでは、pytest-bddを使用しました。これは、開発言語としてはPythonが用いられていたこと、元々ユニットテストがpytestで書かれておりユニットテストの資産流用を考慮したためです。pytest-bddは、pytest※2で振る舞い駆動を実現するために、Gherkinで記載したテストケースとPythonのコードを紐づけてくれる役割を持っています。 - コードの実装
開発者は、pytest-bddで自動化テストを行い、パスするコードを作成しシステムに実装していきました。このステップは、BDDの進め方の「#6 実装」に該当します。
PoCで見えてきた課題と、解決に向けた取り組み
最初は順調に見えたPoCですが、進めていく中で次のような課題が出てきました。
- 多数のテストケースとテストコードが作成されたため、対応関係を理解しにくく、管理が煩雑
- 新機能の実装に専念するため、開発者によるテストコードの作成のための時間が不足
- 開発中に、多くのテストケースを通過させながらコードを実装する際、テスト・実装進捗の管理が難しい
そこで、課題の解決のために、次のような対策を立てました。
- テストケースとテストコードの関連性を明確に管理するための管理ツールを作成する
- 高品質のテストを開発と同時に進めるため、QAエンジニアがテストケースだけではなくテストコードも作成する。
- コード実装の進捗状況をテストのパス数で可視化するための、試験結果・コード実装進捗の表示ツールを作成する。
BDDの開発プロセスにおいて、QAエンジニアが開発の初期段階で、管理ツールや試験結果表示ツールの対応、そしてテストコード作成をサポートしたことにより、開発者の品質向上に対する負荷を軽減し、ソフトウエアの品質を向上させることができました。
まとめ
BDDは、ソフトウェア開発プロセスの品質と効率性を向上させる強力な手法です。現代のビジネス環境は変化し続けており、ソフトウェア開発においては柔軟で迅速な対応が求められます。BDDは自然言語で要件を記述し、シナリオを作成し、迅速なフィードバックを通じて顧客の要求に柔軟に対応するのに非常に効果的です。さらに、開発チームとテストチームが協力し、BDDフレームワークを使用して自動テストを実施することで、生産性の向上、品質の向上、および顧客満足度の向上を期待できます。この記事がBDDを導入のきっかけとなったり、チーム全体で実践を通してソフトウェア開発プロセスの品質向上と効率化を図る参考になれば幸いです。
最後に、AGESTは「OMAKASE BDD」というBDD関連のサービスを提供しており、BDDを様々な言語と環境でサポートしております。初心者の方から既存のBDDユーザーまで、次世代QAエンジニアによるサポートを提供し、独自ツールとプロセスによるリソース管理の効率化を実現します。これにより、製品の品質向上に貢献いたします。お困りごとがありましたら、当社にお気軽にご相談ください。
■株式会社AGEST:OMAKASE BDDサービスページ
APPENDIX:用語の説明
※1 Gherkin: Cucumberなどのテストフレームワークがテストケースを定義するために使用する言語。この言語の目的は、ビジネスアナリストやマネージャを含む開発チーム全体にわたって、BDDの実践を促進することにある。これは、ビジネスマネジメントによる要件定義の初期段階や、開発ライフサイクルの他の段階において、強固で曖昧さのない要件を強制しようとしている。自動テストのためのスクリプトを提供することに加えて、Gherkinの自然言語構文は、テスト対象のコードの簡単な文書化を提供するように設計されている。
※2 pytest:PyPyプロジェクトから生まれたPythonのテストフレームワーク。ユニットテスト、統合テスト、エンドツーエンドテスト、機能テストなど、様々な種類のソフトウェアテストを書くために使うことができる。その機能には、パラメトリックテスト、フィクスチャ、アサート書き換えなどがある。