Webratがスゴい(続:Cucumberがアツい)
Cucumberを使って、Railsアプリのテストを高い抽象度で書き進めていくために欠かせないのがWebratというライブラリです。前回のCucumber全体像の紹介に引き続き、こちらWebratを紹介します。今回も長いです。
今回のまとめ
- Webratすごい
- 画面遷移を「リンクをクリックする」「ボタンをクリックする」と書ける
- リンクのアンカーテキストではまだ日本語が使えず。さきほどパッチ送ったので早晩書けるようになるはず。
- フォームの入力項目もラベルで指定できる
- 今回の話しで書けるようになるfeatureは↓です。
シナリオ: 新しいエントリの登録 前提 エントリ新規作成ページを表示している かつ "タイトル"に"Webratがスゴい(続:Cucumberがアツい)"と入力する かつ "本文"に"Railsアプリのテストを高い抽象度で・・・"と入力する。 かつ "Create"ボタンをクリックする ならば "Webratがスゴい"と表示されていること
Open IDの話はまたはみ出ました。次の回で書きます。そんな引っ張るものでもあるまいにすみません。> 一部の方々
前回までのあらすじ
受け入れテストツールCucumberを使ってみたところ、たいそう凄い感じでした。プレーンテキストを実行可能ということで、お客様と一緒に読み進められる形で、動作する仕様書が書ける、と。さらにいくつかの語彙を日本語で書くことも出来るます。すげー。
シナリオ: 新しいエントリの登録 前提 I am on the new entry page かつ I press "Create" シナリオ: エントリの削除 前提 4つ のエントリがあるなら もし I delete the first entry ならば there should be 3 entries left
Webrat - Ruby Acceptance Testing for Web applications
ここでI am on the new entry pageやI press "Create"に対応するstepを書けば全部日本語にも出来ます。
で。目ざとい人は気づいたと思うのですが、フォームをサブミットすると思われるstepをI press "Create"と書いています。こう書いてもstep側では自分でPOSTしてるんだろ。。。と思ったりするんですが、なんと、実はclicks_button("Create")というメソッドを呼ぶだけで、step側が完了しています。
When /^I press "(.*)"$/ do |button| clicks_button(button) end
つまり。
「ボタンを押す」ということをいろいろ展開してしまうのではなく、文字通り指定したボタンを押すことでリクエストを送れるわけです。これはすごい。
これを実現しているのがWebratというライブラリ。以前に松田さんや角谷さんに教えてもらったやつですね。
http://github.com/brynary/webrat/tree/master
http://webrat.lighthouseapp.com/projects/10503-webrat
これの何が凄いかというと、ユーザ目線のテストが書けるわけです。(あまりないかもしれませんが)あるフォームのPOST先を変えたい場合、自分でPOST先のURLを指定していると「ユーザから見たフローは変わらないのにテストを直さなきゃいけない」という事態になります。
対して、ボタンを指定しておけば自動的に追随してくれますね(逆にボタンテキストの変更で修正が必要になるのはユーザ目線どおりなのでおk)。
webrat_steps.rb の語彙
Webrat stepsで使える語彙は、Cucumberが生成するwebrat_steps.rbを直接見てもらうのがいいと思います。また、${RAILS_ROOT}/features/step_definitions/webrat_steps.rb に同じものが生成されますのでそれを見るのが早いです。
これも正規表現を日本語にすることで簡単に日本語にできます。ちょっと取りかかった時期が古くて語彙が少ないんですけど、私も作ってみました。ソースはこちら。最新化してcontribしたい。ちなみに${RAILS_ROOT}/features/step_definitions/webrat_ja_steps.rbとおけば使えるはず。
- When /言語は"(.*)"/ do |lang|
- When /^"(.*)"ボタンをクリックする$/ do |button|
- When /^"(.*)"リンクをクリックする$/ do |link|
- When /再読み込みする/ do
- When /^"(.*)"に"(.*)"と入力する$/ do |field, value|
- When /^"(.*)"から"(.*)"を選択$/ do |field, value|
- When /^"(.*)"をチェックする$/ do |field|
- When /^"(.*)"のチェックを外す$/ do |field|
- When /^"(.*)"を選択する$/ do |field|
- When /^"(.*)"としてをファイル"(.*)"を添付する$/ do |field, path|
このうち、言語は〜と、再読み込みはオリジナルです。ちょっとGetTextを使ってたんで、ACCEPT_LANGUAGEを指定したくて。
Webratを使って記述したfeature
ということで長いお膳立ての末、日本語でfeatureを書けるようになりました。実例です。まずはこんな感じでfeature/manage_entry.featureを書きます。
フィーチャ: エントリの表示追加更新削除 Hogeサービスのユーザとして、エントリを表示・追加・更新・削除したい シナリオ: 新しいエントリの登録 前提 I am on the new entry page かつ I press "Create"
で、日本語化。
シナリオ: 新しいエントリの登録 前提 エントリ新規作成ページを表示している かつ "Create"ボタンをクリックする
ここで「エントリ新規作成ページを表示している」に対応するstepが必要なのでfeatures/step_definitions/entry_steps.rbなどを作ります。
Given /エントリ新規作成ページを表示している/ do visit new_entry_path end
「"Create"ボタンをクリックする」のほうは前述のwebrat_ja_stepsで動くはず。
実際にはタイトルや本文も必要でするからfeatureに追加します。
シナリオ: 新しいエントリの登録 前提 エントリ新規作成ページを表示している かつ "タイトル"に"Webratがスゴい(続:Cucumberがアツい)"と入力する かつ "本文"に"Railsアプリのテストを高い抽象度で・・・"と入力する。 かつ "Create"ボタンをクリックする
繰り返しになりますが、ここで「タイトル」とか「本文」とかいうラベルテキストを使えるんです。ここで「タイトル」とか「本文」とかいうラベルテキストを使えるんです。重要なことなので2回言いました。もう一回言います。ここで「タイトル」とか「本文」とかいうラベルテキストを使えるんです。
これがもし'input[@name="entry[title]"] に〜'とかだった場合を考えてみると、これがどれだけすばらしいのか分かります。もちろんinputでと書いてもブラックボックスなテストですが、抽象度や何よりお客様に見せられるかどうかが格段に違ってくるはず。Webratすごい。
で、実はこれだけ書いても次のようなことを検証してくれます。
- "タイトル"という中身のラベルがあってそれがinputを指しているか、
- "本文"という中身のラベルが以下同
- "Create"というvalueのtype=submitなinputがあってそれを押す
- 押した先でエラーが出ていない
これで十分な気もしますが、もう少し形を整えましょう。ボタンクリック後の遷移先で入力したエントリが表示されていればいいですかね。
最終形はこんな感じ。
シナリオ: 新しいエントリの登録 前提 エントリ新規作成ページを表示している もし "タイトル"に"Webratがスゴい(続:Cucumberがアツい)"と入力する かつ "本文"に"Railsアプリのテストを高い抽象度で・・・"と入力する。 かつ "Create"ボタンをクリックする ならば "Webratがスゴい"と表示されていること
これってすごくないですか? まだほとんどコードを書いていないわけですが、これがしっかり動く(はず)です。
前のエントリでstepは自分で書いて行かなきゃいけない、ということを言いましたが、画面上の動きについてはこのレベルのものが同梱されています。足りない分は自分でWebratのAPIを使って何かするとしても、十分もとが取れそうな感じ。
Webratちょうお薦めです。すごい。