検索
連載

テスト駆動開発/振る舞い駆動開発を始めるための基礎知識いまさら聞けないTDD/BDD超入門(1)(3/3 ページ)

TDDの概要と進め方、目的と効果、歴史、さまざまな手法への展開、課題に加え、BDDの概要と種類、 重視される考え方などを解説する。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
前のページへ |       

振る舞い駆動開発(BDD)とは

 「振る舞い駆動開発」とは、TDDに触発されてDan North氏により提唱され発展した手法です。

 BDDはTDDの一流派ともいえますが、TDDに対し以下の実現のための原則や工夫が加えられています。

  • テストを「振る舞い」(機能的な外部仕様)の記述に特化させる
  • ユーザーの要求やアーキテクチャの設計仕様といった、より上位のインプットとTDDのテストにつながりを持たせる

 一例として、前述のアウトサイドインTDDもBDDの一種に該当します。なおBDDはTDDから生まれた手法ではあるものの、TDDで欠落しがちになったアジャイルのテストファーストの目的・原則に立ち返るという、原点回帰の方向性も備えています。

 ちなみに今日のBDDは、いろいろな意味や定義で使われる用語になってしまっています。分類としては、テストレベルやテストベースのレベルを基準に、コードレベルとユーザーレベルの2つに分類されることがあります。

コードレベルのBDD

 コードレベルのBDDは、「ユニットテスト」(単体テスト)や、コードレベルの結合テストといったテストレベルを扱う、プログラミングを駆動するためのBDDです。コードレベルのBDDはTDDの一種であり、主に以下に注意が向けられます。

  • テストは、コンポーネントの振る舞いを記述するために書かれる(TDDではテストの目的は限定されていない。振る舞いだけではなく、作業達成のチェックなどを目的に記述されることがある)
  • テストを書く際は、コンポーネントへの要求(コンポーネントがどのような振る舞いをすべきか)の特定を重視する。例えばテストファーストのサイクルに手を付ける前に、前述のアウトサイドインTDDのアプローチを使ってコンポーネント要求を明らかにするアプローチがしばしば採られる(一般的に運用されるTDDでは、前述のインサイドアウトTDDを許容することがある)

 なおコードレベルのBDDのテストコードでは、振る舞いの記述に適したフレームワークを使用するのが一般的です。例えば、「RSpec」「CSpec」などのSpec系フレームワークや、「JBehave」などのBDDフレームワークがBDDでは定番ですが、それらは自然言語に近い構文でテストコードを記述できる特徴を持っています。

require './my_leap'
describe MyLeap do
  it "should determine leap year if divisible by 4" do
      MyLeap.leap?(8).should be_true
  end
  it "should not determine leap year if divisible by 100" do
    MyLeap.leap?(200).should be_false
  end
end 
RSpecで記述されたテストコード

ユーザーレベルのBDD

 ユーザーレベルのBDDは、受け入れテストやEnd-To-Endのシステムテストといったテストレベルを扱う、ユーザー要求や外部仕様の実現を駆動するBDDです。テストファーストの一種ですが、主に以下の特徴を持っています。

  • ユーザー要求や外部仕様を、自動化された受け入れテストやシステムテストで記述する。テストの記述には、自然言語のようにテストを書けるセミフォーマルな言語や、ユーザーが可読できるドメイン特化言語(Domain-Specific Language、DSL)がよく用いられる
  • アジャイル開発における「イテレーション」などの大きな単位で、テスト失敗→テスト成功のテストサイクルを回していく(テストサイクルを数十秒から数十分で回すプログラミング手法としてのTDDとは異なるスタイルを採る)

 また、ユーザーレベルのBDDは、シンプルなルールや原則で構成されるTDDと違って、ユーザー要求をどう獲得・分析して、設計に導いていくかといったプロセスも包含した手法となっています。

 ユーザーレベルのBDDで記述されるテストの一例を下記に示します。

Feature: ウェブページの表示と遷移テスト
  Google検索でウェブページの表示と遷移を確認します
  Scenario: Searching for test
    Given "https://www.google.com/"を開く
    When "test"を入力してボタンをクリックする
    Then "test - Google Search"というタイトルページが表示されること
BDDフレームワーク「Cucumber」でのEnd-To-Endテストのスクリプトの例

Cucumber

 ユーザーレベルのBDDでは、テストの記述に特定のフォーマットに合わせるセミフォーマルなアプローチが好まれます。

 例えばアジャイルでは、しばしば「ユーザーストーリー」の形式でテストを記述します。テストの拡張性を重視する場合は「データ駆動テスト」や「キーワード駆動テスト」の構造をテストの記述に導入する場合もあります。

BDDで重視される2つの考え方

 BDDでは、テストの記述において「Tests as Documentation」「Specification by Example」という2つの考え方が重視されます。

【1】「Tests as Documentation」(ドキュメントとしてのテスト)

 「Tests as Documentation」はテストをドキュメントとして扱うアプローチです。テストの可読性を上げ、テスト対象の振る舞いを分かりやすく記述することにより、テストをテスト対象の詳細仕様書のように扱えるようにします。これはテスト対象の保守に活用されます。

【2】「Specification by Example」(例示による仕様)

 「Specification by Example」は、例示による要求や仕様の記述を活用するための包括的な考え方です。例示を使って要求獲得や要求仕様化を行うことで、ユーザーとのコラボレーションや変化への対応、ユーザー要求と設計との関連付けを促進することを目的としています。

 前述のTests as Documentationは、Specification by Exampleで中心的なアプローチの1つです。Specification by ExampleはBDDやATDDを支える、さまざまなプロセスを定義しており、BDDの基礎を支える考え方と位置付けられています。

次回から、BDDやアウトサイドインTDDについて具体的に

 やや駆け足でしたが、TDDの発展や他への展開について解説しました。今後の連載では、今回挙げたBDDやアウトサイドインTDDについて、具体的な事例を用いて解説していく予定です。

Copyright © ITmedia, Inc. All Rights Reserved.

前のページへ |       
ページトップに戻る