オブジェクトの広場はオージス総研グループのエンジニアによる技術発表サイトです

アジャイル

OGIS Scalable Agile Method 2.0入門 第4回

受け入れテスト駆動開発の概要
株式会社オージス総研 技術部アジャイル開発センター 張 嵐
2016年3月10日

本記事では、OGIS Scalable Agile Method 2.0(以降、OSAM2.0と略す)基本形の構成要素の1つである受け入れテスト駆動開発(以降、A-TDDと記す)の概要を説明する。A-TDDは受け入れ側と開発側が協同で、全員が読める言語で受け入れテストを先に書き、その実行を自動化するアプローチである。本記事では、A-TDDの基本概念、A-TDDを支援するツールを利用したA-TDDの実施例を中心に述べる。

受け入れテスト駆動開発 A-TDD とは

開発に関わる人々がそれぞれ異なるスキルを駆使し、分断されたフェーズで、分業的に作業を行う開発スタイルがある。このような開発スタイルは、関係者間の情報伝達、ドキュメントによる作業の引き継ぎなどで情報の損失や、互いのフィードバックの遅延が発生しやすいという問題がある。

A-TDDは、下図で示すように、受け入れ側と開発側が協同で、全員が読める言語で受け入れテストを先に書き、その実行を自動化するアプローチである。これにより、作成した受け入れテストケースは業務の合理性、技術の実現可能性及び例外条件や境界値など、より全面的に理解され、検討される。そのことを通じて、価値のある品質の良い製品を開発できる。

図. A-TDDのイメージ
[図. A-TDDのイメージ]

注:A-TDDのイメージ図では、ネットショップの新規顧客を増やすため新規登録のユーザーに対して10%の割引き率を適用するケースを記載している。

A-TDDと類似のアプローチとして

  • 振る舞い駆動開発(BDD:Behavior-Driven Development)
  • 実例仕様(SBE:Specification by Example)
  • アジャイル受け入れテスト(Agile Acceptance Testing)
  • ストーリーテスト(Story Testing)

等があるが、本章の説明では以下の表で示すように、「受け入れ側と開発側が協同で、あらかじめ受け入れテストを書き、その一部の実行を自動化する」ことをA-TDDとして定義する。

定義 目的 手段
受け入れ側(顧客)、開発側(分析者、開発者、テスト担当者)が協同で、 開発内容に関する共通認識を持つ 役割間の協力(顧客、業務、技術)
受け入れテストを先に書き、 要求をテストケースとして、文書化し、維持する Given-When-Then形式
一部の実行を自動化する 回帰テストによる継続な検証を可能とする 自動化ツール

上記の定義から、A-TDDを実施することによって、以下のメリットが享受できる。

  • 受け入れテストを開発の早い時点から書くことで、受け入れ側と開発側の理解の違いが早期に発見できる。
  • 受け入れテストを全員が読める言語で記述することで、要求の可読性が向上し、要求の曖昧さを排除できる。
  • 受け入れテストを開発の早い段階から実行することで、受け入れテストは「実行可能な仕様」 [1] として作成され、保守していくため、ドキュメントの整合性問題を回避できる。

すなわち、A-TDDの導入によって適切な製品が開発される確率を高めていくのである。

注:実行可能な仕様
原語は、”Executable specification”。書籍 [1] では、”Executable specification”を機能の階層で構造化し、生きた文書化 (”Living documentation”)を行うことが推奨されている。

A-TDDを支援するツール

1996年にA-TDDはXPのプラクティス「自動化されたテスト」で紹介されたが、普及し始めたのは2002年のWard Cunningham によるサポートツールFitの公開からである。A-TDDは「自動化」を強いてないが、開発者はシステムから迅速なフィードバックが得られ、回帰テストも実施しやすくなるため、受け入れテストの自動化をサポートするツールが重要な役割を果たす。

2006年以降、A-TDDをより実施しやすくするため、さまざまなサポートツールが登場した。大まかに以下のように分類できる。

  • テーブル形式で要求を表現する:
    Fit/FitNesse、Robot Frameworkなど
  • 「Given – When - Then」形式で要求を表現する:
    easyb、JBehave、GSpec、Instinct、JDave、beanSpec、tumbler-glass、JRuby+Rspec、Groovy+Spock、Cucumber+Java、Systir、specs2、scalacheck、ScalaMockなど
  • GUI経由のテスト形式:
    Selenium、Web2Test、StoryTestIQなど

「OSAM2.0」では、上記のツールに対し調査と評価を行い、以下の表で示す導入の容易さと実用性から、A-TDDのサポートツールとしてCucumberの利用を推奨している。

評価項目
導入の容易さ ドキュメント管理の容易さ
環境構築の容易さ
受け入れでの利用の容易さ
実用性 受け入れテストの記述のやすさ
自動化コード作成の容易さ
受け入れテストの読みやすさ
受け入れテスト実行の容易さと結果の見やすさ

CucumberではGherkinと呼ばれる言語で受け入れテストを記述する。Gherkinはテキスト形式の日本語でも記述でき、Given、When、Thenと言ったいくつかのキーワードが用意されている。Cucumberを利用する場合、以下のような手順でA-TDDを実施する。

  1. Excelテンプレート(※)を利用し、受け入れテストをGherkin形式(「Given-When-Then:テストケースの記述」を参照)で記述する。
  2. Excelのマクロ(※)を利用し、上記のGherkin形式で作成した受け入れテストを実行するための「.feature」ファイルを生成する。
  3. Cucumberで受け入れテストを実行するための「Runner」クラスとテストコードを記述するための「Step Definition」クラスを実装する。(「OSAM2.0におけるA-TDDの実行」を参照)
  4. JUnitやMavenを利用し、「Runner」が「 .feature」ファイルを参照しつつ、「 Step Definition」を順番に実行し、対象システムの検証を行う。

(※)Excelテンプレートとマクロは、受け入れテストの記述しやすさと読みやすさのために当社が作成したもので、Cucumberが提供するものではない。

下図はCucumberを利用する場合、A-TDDを実施するための各ファイルと実装する必要があるクラスの構成を示す。

Cucumber利用時のファイル/クラス構成
[図.Cucumber利用時のファイル/クラス構成]

A-TDDのコスト

A-TDDの導入は、以下のコストが伴うことを念頭にしなければならない。これらのコストは当社の試行プロジェクトの実績では開発コストの8%~45%に達した。 [2]

  • 学習コスト
  • 受け入れテスト作成のコスト
  • 自動化のコスト
  • 受け入れテストの保守コスト

上記のコストを低減し、かつ適用効果を高くするためには、まず、A-TDDの導入によって解決したい課題の分析を行い、それから、A-TDDの実施対象を選定し、サポートツールの選択や受け入れテスト自動化の範囲を検討する必要がある。

「OSAM2.0」では、A-TDDを導入する場合、以下2つの指針を提供する。

  • A-TDDの実施対象としてビジネスロジックにフォーカスする
  • 自動化の対象は、まず重要な業務フローに着目する

A-TDDの実施対象としてビジネスロジックにフォーカスする

Cucumberは柔軟なツールで、GUI経由のサポートツール、例えばSeleniumと組み合わせて受け入れテストの自動化を実施できる。GUI経由の受け入れテストは、実際のユーザー操作に近い状態でテストできるというメリットがあるが、以下のようなデメリットもある。

  1. GUIは頻繁に変わりやすく、それに追従するコストが大きい
  2. 受け入れテストを自動化する時、セットアップや結果へのアクセス処理が複雑になる

すなわち、GUI経由の受け入れテストは受け入れテストの作成コストと保守のコストをともに高める可能性がある。このため、受け入れテスト自動化を検討する際にできるだけGUIのテストとビジネスロジックのテストを分離することが望ましい。

下図はMike Cohnのテスト自動化のピラミッドを示す。同様に、GUI経由の自動化テストを少なくすることを推奨している。
Cucumber利用時のファイル/クラス構成
[図.Mike Cohnのテスト自動化ピラミッド]

自動化の対象は、まず重要な業務フローに着目する

受け入れテストの自動化はコストがかかるため、自動化対象の費用対効果を事前に検証すべきである。費用対効果が十分でない部分には手動テストの併用を考える。

当社の検証では、重要な業務フロー(ユーザーが一連の操作を通じて業務目的を達成するための流れ)にフォーカスし、受け入れテストを作成し、自動化を行うことで、テストの自動化による工数の増加を開発工数の8%に収めることができた。

Given-When-Then:テストケースの記述

A-TDDは受け入れ側と開発側のコラボレーションによって初めて成り立つ。そのために、最も重要なことは受け入れテストを「自然言語」で記述できることである。また、上記「A-TDDを支援するツール」で述べたツールによって作成した受け入れテストを自動化するため、一定の形式を定めなければならない。

受け入れ側と開発側が自然言語で読め、かつ自動化できるという両方の条件を満たすため、「Given-When-Then」(GWT、前提-場合-結果)は受け入れテストを記述する形式の一種として登場した。

予約語 意味
Given テストの事前条件をこの部分で記述する ○○な状態/状況で
When 具体的な操作を記述する ××をしたら
Then 期待する結果を記述する △△が起きる/結果になる

DtoDでは、プロダクトオプションを調査し、確認するためにGWTを用いる。作成した受け入れテストは計画ビューによって、具体化の程度が異なる。現在ビューでは、最も正確かつ具体的でテスト可能な受け入れテストが作成可能である。

用語注:DtoD
DtoD(Discover to Deliver)は、スクラムのプロダクトバックログ項目であるユーザーストーリーの考案を支援するフレームワークである。DtoDでは3つの時間軸とプロダクトの7側面という観点を用いて、プロダクトに対するニーズとその実現スケジュールを利害関係者間で話し合い、合意する具体的な方法を示す。

用語注:現在ビュー
DtoDでは3つの計画策定期間に対して計画/分析セッション(DtoDでは要求定義、分析、計画策定を行うワークショップを計画/分析セッションと呼ぶ)を開催する。現在ビューはこの計画策定期間の一つで、次の反復を計画範囲としてどのようなシステムやプロダクトを計画するかを検討する。

DtoDが推奨する受け入れテストの記述テンプレート
[DtoDが推奨する受け入れテストの記述テンプレート(EBG Consultingによる提供)]

上図は、DtoDで用いられるユーザーストーリーの確認時の受け入れテストを記述するためのテンプレートである。このような記述テンプレートを利用することで、受け入れ側と開発側がビジネスドメインの言語でコミュニケーションできるし、開発の目標を確認できる。また、開発の前提となり、将来的に拡張や変更を行う可能性があるビジネスルールのドキュメントとして利用できる。

作成した受け入れテストから自動化対象を選定する場合には、受け入れテストから迅速なフィードバックが求められているかどうかを考慮することが望ましい。Cucumberで受け入れテストの自動化を行う場合、受け入れテストをGherkinと呼ばれるGWT形式で記述し、拡張子「.feature」のファイルとして保存する。一般的に「.feature」ファイルでは受け入れテストを、フィーチャー (とストーリー)、シナリオ及びステップ(Given、When、Then)の 3 階層で記述する。

以下の図では、DtoDが推奨するテンプレートで作成した内容を「.feature」ファイルに取り入れる方法を示す。

DtoDのテンプレートから「.feature」ファイルを作成する例
[DtoDのテンプレートから「.feature」ファイルを作成する例]

一般的に、DtoDの事前ビューでは、フィーチャー(ユーザーストーリー)とシナリオを識別する。現在ビューでは、各ステップとステップに対する具体的なデータ例を追加していく。

用語注:事前ビュー
DtoDで計画/分析セッションを開催する際の計画策定期間の一つ。事前ビューでは次のリリースを計画範囲として、どのようなシステムやプロダクトを計画するかを検討する。

OSAM2.0におけるA-TDDの実行

以下、A-TDDのサポートツールCucumberを利用したA-TDDの実行の流れを概説する。

  1. 「.feature」ファイルの作成
    1. フィーチャーの作成
      ビジネス目標を達成するために、受け入れ側と開発側は知識と経験を共有しながら、自然言語を用いて受け入れテスト対象を定義する。「OSAM2.0」では、重要な業務フローやビジネスルールを検証するために作成する。
    2. シナリオの作成
      自然言語で、ユーザーがシステムをどのように利用するかを記述する。
    3. ステップの作成(Given-When-Then)
      自然言語の曖昧さを排除するため、作成したシナリオに対し実例(データなど)を用いて、説明する。また、自動化のために、洗練化を行う。
  2. 自動化コードの作成 Cucumberで実行するためのRunnerクラスと個々のステップに紐付けるテストコードを実装するStep Definitionクラスを作成する。
  3. Maven、Ant、JUnit、Jenkinsなどを利用し、実行する

フィーチャー、シナリオ及びステップはGWTで作成されるため、開発側(開発者、要求分析者、テスター)及び受け入れ側にいるユーザーのどちらが記述してもよい。自動化コードについて、開発側はCucumberで生成した自動化のための雛形を利用し、作成していく。受け入れテストの実行は受け入れ側と開発側が協力しながら行う。

A-TDDとOSAM2.0の課題の関係

第2回で説明したOSAM2.0の課題がA-TDDによりどのように解決されるかをまとめたものが次の表である。

課題 A-TDDによる解決
A. プロダクトバックログの項目をどのように定義するか
B. プロダクトバックログに対応して作成されたものをどのように受け入れるか プロダクトバックログ項目に対応する受け入れテストを受け入れ側と開発側が協同で作成し、それを用いて、開発されたものの受け入れを行う。また、受け入れテストを自動化することで、繰り返しの実行が可能になる。
C. 仕様が暗黙知化し、開発者の理解の違いで仕様の不整合や仕様の抜けが発生するのを如何に防ぐか 受け入れテストを先に書くことによって、受け入れ側と開発側の理解の違いが早期に発見できる。また、要求の実例化により可読性が向上でき、要求の曖昧さを排除される。
D. リリースの見通しに関してどのように検討すべきか
E. プロダクトのドキュメントをどうするか 受け入れテストは「実行可能な仕様」として作成され、保守していくため、ドキュメントの整合性問題が回避される。
F. プロダクトの最低限の品質をどう確保するか 顧客、開発者協同で受け入れテストを完成させるため、要求の確実性が向上する。また、重要なビジネスフローやビジネスルールに対し、自動化された受け入れテストがあり、テスト実行のオーバヘッドが低減されるので、品質確保できる。
G. プロダクトオーナーの役割が重すぎる

第 4 回の終わりに

本記事では、OSAM2.0 基本形の構成要素の1つである受け入れテスト駆動開発(A-TDD)の概要、A-TDDを支援するツールを利用したA-TDDの実行の流れを中心に説明した。

次回の記事では、OSAM2.0 基本形での開発の流れを説明する。

参考文献

[1] Gojko Adzic, Specification by example, Manning, 2011
[2] 張 嵐, 木村 めぐみ, 藤井 拓, B-027「受け入れテスト駆動開発による実行可能な仕様に関する検証結果」, FIT2015(第14回情報科学技術フォーラム),一般社団法人 情報処理学会, 2015, p.230