{{toc}} !Cucumberについて !!概要 Cucumberが提供するBDDの内容をまとめると ""BDDはフルスタックのアジャイル開発技法です.BDDはATDP(Acceptance Test-Driven Planning)と呼ばれるAcceptance TDDの一種を含め,エクストリームプログラミングからヒントを得ています.ATDPでは,顧客受け入れテストを導入し,それを主体にコードの開発を進めて行きます.それらは顧客と開発チームによる共同作業の結果であることが理想的です.開発チームによってテストが書かれた後,顧客がレビューと承認を行うこともあります.いずれにしても,それらのテストは顧客と向き合うものなので,顧客が理解できる言語とフォーマットで表現されていなければなりません.Cucumberを利用すれば,そのための言語とフォーマットを手に入れることができます.Cucumberは,アプリケーションの機能とサンプルシナリオを説明するテキストを読み取り,そのシナリオの手順に従って開発中のコードとのやり取りを自動化します[1, 7pp.]. と記されている. !!features Cucumberでは先の引用にある通り、振る舞いをシナリオとしてまず記述します. 次に,英語のfeaturesのひな形を示します. <<< ruby % cat ./featrues/sample_e.feature Feature: Description of feature Scenario: Description of scenario Given I want to explain scenario Then I investigate When I know the meaning >>> ファイルの先頭で, # language: ja と記すと日本語でのkeywordが認識されます.下記にmy_todoに対するfeaturesファイルの具体例を示します. <<< tcsh # language: ja 機能: todoの更新を行う todoは更新していくものであり,新しく書いたり終わったものを消したいので バックアップをとって,過去のtodoを残しておく シナリオ: コマンドを入力してtodoを更新していく 前提 todoを編集したい もし "my_todo --edit"と入力する ならば editが開かれる かつ 自分のtodoを書き込む シナリオ: コマンドを入力してバックアップをとる 前提 todoの編集が終わった もし "my_todo --store [item]"と入力する ならば itemのバックアップを取る >>> このようにFeature, Scenario, Given, Then, Whenなどのcucumberが解釈する大文字で始まる keywordsに対して,それぞれ機能,シナリオ,前提,もし,ならばなどの単語があてられています. この機能により,より自然な日本語でfeaturesを書くことができ, 顧客にもわかりやすく,開発者も書きやすくなっています。 featureファイルで用意されているkeywordは cucumber --i18n LANG によって表示される.LANG=ja, enに対しては下記の通りになっています. || keyword || ja(japanese) || en(english) ||^ feature||^ "フィーチャ", "機能" ||"Feature", "Business Need", ||"Ability" || || background|| "背景"|| "Background" || || scenario|| "シナリオ" || "Scenario" || ||^^ scenario_outline || "シナリオアウトライン",||"Scenario Outline", || "シナリオテンプレート","テンプレ",||^ "Scenario Template" || || "シナリオテンプレ" || examples|| "例", "サンプル" || "Examples", "Scenarios" || || given ||"* ", "前提" || "* ", "Given " || || when ||"* ", "もし" || "* ", "When "|| || then || "* ", "ならば" || "* ", "Then "|| || and || "* ", "かつ" || "* ", "And " || || but || "* ", "しかし", "但し", "ただし"|| "* ", "But " || || given (code) || "前提" || "Given" || || when (code) || "もし" || "When" || || then (code) || "ならば" || "Then" || || and (code) || "かつ" || "And" || || but (code) || "しかし", "但し","ただし" || "But" || !!Cucumber,RSpecインストール まずrspecをgemでinstallする. #gem install rspec --version 2.0.0 #rspec --help と入力して <<< tcsh /Users/nasubi/nasu% rspec --help Usage: rspec [options] [files or directories] >>> のような表示がされていればinstallができている.次に,cucumberをinstallする #gem install cucumber --version 0.9.2 #cucumber --help と入力して <<< tcsh cucumber --help Usage: cucumber [options] [ [FILE|DIR|URL][:LINE[:LINE]*] ]+ >>> のような表示がされていればinstallできている. !!ディレクトリー構造と使用手順 cucumberはRubygemsの提供する基本directory構造での作業を前提としています. その構造を表示すると次のようになります. <<< bob% tree . . ├── Gemfile ├── Rakefile ├── features │ ├── hogehoge.feature │ ├── step_definitions │ │ └── hogehoge_step.rb │ ├── support │ ├── env.rb ├── lib │ ├── daddygongon │ │ ├── emacs_help.yml │ │ ├── my_todo.yml ├── pkg ├── spec │ ├── my_help_spec.rb │ ├── my_todo │ │ ├── todo_spec.rb │ ├── spec_helper.rb │ └── support │ └── aruba.rb >>> カレントディレクトリ(.)の中にfeaturesというサブディレクトリを作成します. そのfeaturesの中に書きたいシナリオを書いた,hogehoge.featureを作成します. featureの具体例は上記に示してします. 次にシェルを開いて,カレントディレクトリで, cucumber features hogehoge.feature と入力します.そうすると以下のような出力が得られます. <<< ruby Feature: Description of feature Scenario: Description of scenario # features/hogehoge.feature:3 Given I want to explain scenario # features/hogehoge.feature:4 Then I investigate # features/hogehoge.feature:5 When I know the meaning # features/hogehoge.feature:6 1 scenario (1 undefined) 3 steps (3 undefined) 0m0.066s You can implement step definitions for undefined steps with these snippets: Given(/^I want to explain scenario$/) do pending # Write code here that turns the phrase above into concrete actions end Then(/^I investigate$/) do pending # Write code here that turns the phrase above into concrete actions end When(/^I know the meaning$/) do pending # Write code here that turns the phrase above into concrete actions end >>> ここではステップ定義に使用することができるコードブロックが表示されています. ステップ定義はステップを作成するための方法です.このサンプルでは,Giver(), When(), Then()の 3つのメソッドを使ってステップを記述します. これらのメソッドはそれぞれ\/\/で囲まれたRegexp(正規表現)とブロックを受け取ります. Cucumberはシナリオの最初のステップを読み取り,そのステップにマッチする正規表現を持つステップ定義を探します. その中の対応するステップ定義のブロックを実行します. これはfeaturesディレクトリの下にstep_definitionsディレクトリーにあることになっています. このシナリオを成功させるには,Cucumberが読み込めるファイルにステップ定義を保存する必要があります[1, pp15.]. その内容は次の通りcucumberから自動生成されます. <<< ruby Given(/^I want to explain scenario$/) do pending # Write code here that turns the phrase above into concrete actio\ ns end Then(/^I investigate$/) do pending # Write code here that turns the phrase above into concrete actio\ ns end When(/^I know the meaning$/) do pending # Write code here that turns the phrase above into concrete actio\ ns end >>> pendingを削除して,そこにあれば良いなと思うコードを記述していきます. ここまでがCucumberの使用方法のテンプレートです.