Cucumber にふれてみた

moroさんに背中を押され、Cucumber をお仕事で作っているソフトで試してみました。
http://cukes.info/images/cuke_logo.png

インストールと初期設定

既にRSpecは入っている場合

% sudo gem install cucumber webrat
% cd Railsプロジェクト
%  script/generate cucumber

ここで、Cucumberを動かす為の設定等が出来ます。Cucumber自体は日本語などの自然言語でテストシナリを書けるフレームワーク的なもので、実際のテスト機能は含まれていません。ここでは実際のテストはWebratというWebアプリの受入テスト用ソフトでおこないます。

features/step_definitions/webrat_steps.rb に記述されているのが、自然言語と実際のテストを繋ぐ Step definitionsです。
ただし、英語用なので id:moro さんが作られた 日本語用 webrat_ja_steps.rb をダウンロードし features/step_definitionsに入れます。

feature (steps) を書く

まずは簡単そうなログイン処理のfeature(シナリオ)を features/logins.feature ファイルに書いてみました。

フィーチャ: ログイン
  利用者がログインしてみる
  
  シナリオ: 登録されたメールアドレス、パスワードでログイン
    もし "ログインページ" へアクセス
    かつ "メールアドレス"に"xxxx@xxxx.com"と入力する
    かつ "パスワード"に"yyyyy"と入力する
    かつ "ログイン"ボタンをクリックする
    ならば "ログイン成功"と表示されていること
  
  シナリオ: 登録されたメールアドレス、登録されてないパスワードでログイン
    もし "ログインページ" へアクセス
    かつ "メールアドレス"に"xxxx@xxxx.com"と入力する
    かつ "パスワード"に"zzzzz"と入力する
    かつ "ログイン"ボタンをクリックする
    ならば "メールアドレスかパスワードが正しくありません"と表示されていること

現在の webrat_ja_steps.rb には 〜 へアクセスの が定義されてないので以下を追加しました。

When /"(.*)" へアクセス/ do |page_name|
  visit path_to(page_name)
end

また、シナリオ内に現れるページ名ですが /customer のように直にパスを書く事も出来ますが features/support/paths.rb ファイルにページ名とURLの対応コードを書く事でシナリオをより自然な感じにできます。

module NavigationHelpers
  # Maps a name to a path. Used by the

  def path_to(page_name)
    case page_name
    
    when /ホームページ/
      '/'
    when /ログインページ/
      authentications_path
   else
      raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
        "Now, go and add a mapping in #{__FILE__}"
    end
  end
end

World(NavigationHelpers)

実行

実行は cucumber コマンドで行います。ただしは言語設定 -l ja オプションで日本語を指定します。

% cucumber features -l ja
フィーチャ: ログイン
  利用者がログインしてみる

  シナリオ: 登録されたメールアドレス、パスワードでログイン      # features/logins.feature:4
    もし "ログインページ" へアクセス               # features/step_definitions/webrat_ja_steps.rb:4
fills_in is deprecated. Use fill_in instead.
    かつ "メールアドレス"に"xxxx@xxxx.com"と入力する # features/step_definitions/webrat_ja_steps.rb:24
fills_in is deprecated. Use fill_in instead.
    かつ "パスワード"に"yyyyy"と入力する         # features/step_definitions/webrat_ja_steps.rb:24
    かつ "ログイン"ボタンをクリックする              # features/step_definitions/webrat_ja_steps.rb:12
    ならば "店舗管理"と表示されていること             # features/step_definitions/webrat_ja_steps.rb:50

  シナリオ: 登録されたメールアドレス、登録されてないパスワードでログイン     # features/logins.feature:11
    もし "ログインページ" へアクセス                     # features/step_definitions/webrat_ja_steps.rb:4
    かつ "メールアドレス"に"xxxx@xxxx.com"と入力する       # features/step_definitions/webrat_ja_steps.rb:24
    かつ "パスワード"に"zzzzz"と入力する               # features/step_definitions/webrat_ja_steps.rb:24
    かつ "ログイン"ボタンをクリックする                    # features/step_definitions/webrat_ja_steps.rb:12
    ならば "メールアドレスかパスワードが正しくありません"と表示されていること # features/step_definitions/webrat_ja_steps.rb:50

2 scenarios (2 passed)
10 steps (10 passed)
0m0.264s

fills_in is deprecated. Use fill_in instead. というワーニングが出ます。これは webrat_ja_steps.rb の対応するカ所をメッセージ通りに直せばOKです(バージョンアップしてAPIが変わったのですね)。

それから、featureやstepsの対応行が出るのは上手く行かない場合には有効ですが、やや くどい と思う場合は -s オプションを付けると消えます。

% cucumber features-sl ja 
フィーチャ: ログイン
  利用者がログインしてみる

  シナリオ: 登録されたメールアドレス、パスワードでログイン
    もし "ログインページ" へアクセス
    かつ "メールアドレス"に"xxxx@xxxx.com"と入力する
    かつ "パスワード"に"yyyyyy"と入力する
    かつ "ログイン"ボタンをクリックする
    ならば "店舗管理"と表示されていること

  シナリオ: 登録されたメールアドレス、登録されてないパスワードでログイン
    もし "ログインページ" へアクセス
    かつ "メールアドレス"に"xxxx@xxxx.com"と入力する
    かつ "パスワード"に"zzzzzz"と入力する
    かつ "ログイン"ボタンをクリックする
    ならば "メールアドレスかパスワードが正しくありません"と表示されていること

2 scenarios (2 passed)
10 steps (10 passed)
0m0.262s

Cucumberの実行は features/support/env.rb, config/database.yml を見ると判るように RAILS_ENV=cucumber と独自の環境で動いています。ただし、DBはデフォルトでは test環境を使っています。

感想など

受入テスト(総合テスト?)が日本語で書けるのは確かに素晴らしいです。しかも、内部は正規表現により実行するコードとの対応を取るというシンプルなアーキュテクチャーでプログラマー的にも安心感があります。


ただし、まだ日本語(英語も?)の情報は少なすぎます ^^);
今回ここまで作るのに、


まだ、「もし」「かつ」「ならば」がまだしっくりときてない。それから フィーチャ: や シナリオ: に書くコメントをどのように書けばよいのかが解らない・・・ たくさん書きながら思索するしかないのかな・・・・?

つづく・・・