\subsection{Cucumberについて} \subsubsection{概要} Cucumberが提供するBDDの内容をまとめると \begin{quotation} BDDはフルスタックのアジャイル開発技法です.BDDはATDP(Acceptance Test-Driven Planning)と呼ばれるAcceptance TDDの一種を含め,エクストリームプログラミングからヒントを得ています.ATDPでは,顧客受け入れテストを導入し,それを主体にコードの開発を進めて行きます.それらは顧客と開発チームによる共同作業の結果であることが理想的です.開発チームによってテストが書かれた後,顧客がレビューと承認を行うこともあります.いずれにしても,それらのテストは顧客と向き合うものなので,顧客が理解できる言語とフォーマットで表現されていなければなりません.Cucumberを利用すれば,そのための言語とフォーマットを手に入れることができます.Cucumberは,アプリケーションの機能とサンプルシナリオを説明するテキストを読み取り,そのシナリオの手順に従って開発中のコードとのやり取りを自動化します[1, 7pp.]. \end{quotation} と記されている. \subsubsection{features} Cucumberでは先の引用にある通り、振る舞いをシナリオとしてまず記述します. シナリオとは,一つひとつの振る舞いを,主にGiven(前提), Then(もし), When(ならば)に分けてfeaturesを記述します. 次に,英語のfeaturesのひな形を示します. \begin{lstlisting}[style=customRuby,basicstyle={\scriptsize\ttfamily}] % 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 \end{lstlisting} ファイルの先頭で, \begin{quote}\begin{verbatim} # language: ja \end{verbatim}\end{quote} と記すと日本語でのkeywordが認識されます.下記にmy\_todoに対するfeaturesファイルの具体例を示します. \begin{lstlisting}[style=customCsh,basicstyle={\scriptsize\ttfamily}] # language: ja 機能: todoの更新を行う 自分のするべきことを書き込むためにtodoを更新する シナリオ: コマンドを入力してtodoを更新していく 前提 todoを編集したい もし "my_todo --edit"と入力する ならば editが開かれる かつ 自分のtodoを書き込む \end{lstlisting} このようにFeature, Scenario, Given, Then, Whenなどのcucumberが解釈する大文字で始まる keywordsに対して,それぞれ機能,シナリオ,前提,もし,ならばなどの単語があてられています. この機能により,より自然な日本語でfeaturesを書くことができ, 顧客にもわかりやすく,開発者も書きやすくなっています。 featureファイルで用意されているkeywordは \begin{quote}\begin{verbatim} cucumber --i18n LANG \end{verbatim}\end{quote} によって表示される.LANG=ja, enに対しては表\ref{table:one}の通りになっています. \begin{table}[htbp]\begin{center} \caption{featureファイルで用意されているkeywordの日本語(ja),英語(en)の対応表.} \label{table:one} \begin{tabular}{llll} \hline keyword &ja(japanese) &en(english) \\ \hline 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" \\ \hline \end{tabular} \label{default} \end{center}\end{table} %for inserting separate lines, use \hline, \cline{2-3} etc. \subsubsection{Cucumber,RSpecインストール} まずrspecをgemでinstallします. \begin{enumerate} \item gem install rspec --version 2.0.0 \item rspec --help \end{enumerate} と入力して \begin{lstlisting}[style=customCsh,basicstyle={\scriptsize\ttfamily}] /Users/nasubi/nasu% rspec --help Usage: rspec [options] [files or directories] \end{lstlisting} のような表示がされていればinstallができています. 次に,cucumberをinstallします. \begin{enumerate} \item gem install cucumber --version 0.9.2 \item cucumber --help \end{enumerate} と入力して \begin{lstlisting}[style=customCsh,basicstyle={\scriptsize\ttfamily}] cucumber --help Usage: cucumber [options] [ [FILE|DIR|URL][:LINE[:LINE]*] ]+ \end{lstlisting} のような表示がされていればinstallできています. \subsubsection{ディレクトリー構造と使用手順} CucumberはRubygemsの提供する基本directory構造での作業を前提としています. その構造を表示すると次のようになります. \begin{quote}\begin{verbatim} 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 \end{verbatim}\end{quote} カレントディレクトリ(.)の中にfeaturesというサブディレクトリを作成します. そのfeaturesの中に書きたいシナリオを書いた,hogehoge.featureを作成します. featureの具体例は上記に示しています. 次にシェルを開いて,カレントディレクトリで, \begin{quote}\begin{verbatim} cucumber features hogehoge.feature \end{verbatim}\end{quote} と入力します.そうすると以下のような出力が得られます. \begin{lstlisting}[style=customRuby,basicstyle={\scriptsize\ttfamily}] 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 \end{lstlisting} ここではステップ定義に使用することができるコードブロックが表示されています. ステップ定義はステップを作成するための方法です.このサンプルでは,Giver(), When(), Then()の 3つのメソッドを使ってステップを記述します. これらのメソッドはそれぞれ\/\/で囲まれたRegexp(正規表現)とブロックを受け取ります. Cucumberはシナリオの最初のステップを読み取り,そのステップにマッチする正規表現を持つステップ定義を探します. その中の対応するステップ定義のブロックを実行します. これはfeaturesディレクトリの下にstep\_definitionsディレクトリーにあることになっています. このシナリオを成功させるには,Cucumberが読み込めるファイルにステップ定義を保存する必要があります[1, pp15.]. その内容は次の通りCucumberから自動生成されます. \begin{lstlisting}[style=customRuby,basicstyle={\scriptsize\ttfamily}] 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 \end{lstlisting} pendingを削除して,そこにあれば良いなと思うコードを記述していきます. ここまでがCucumberの使用方法のテンプレートです.