日別アーカイブ: 2012 . 3 / 19

Ruby on Rails: The RSpec Book 読破記録: 15章から18章

■15章ではRSpecを快適に使うためのTipsが書かれています。

RSpec実行のオプションやエディタ、オートメーション化、Rake、RCovなどが紹介されています。

私はすでに紹介されているいくつかを開発環境に導入済みです。Ruby on Railsを使っているのでRake、それからrspec_railsRCovはよく知っています。Autotestは使っていませんが、同様の機能をGuardで実装しています。またエディタはTextMateの評判がいいのですが、LinuxなのでGeditプラグインをいくつか入れて使っています。Redcarも使ってみたのですが、日本語がどうも、、私には合いませんでした。

■16章ではRSpecをカスタマイズして使う方法が紹介されています。

・実行するサンプルとしないサンプルを分ける。
・モジュールを追加する
・before,after,aroundのグローバルフック
・14章でもすこし説明されていたMockの選択
・カスタムマッチャ
・カスタムフオーマッタ

などです。中でもカスタムマッチャはよく使いそうです。

RSpecをカスタマイズするのはもう少しデフォルトの状態に慣れてからでもよさそうです。デフォルトの状態でも十分に高機能だと感じていますし、現段階でわからないことがあってもいいかなぁと思います。さらに読み進めます。

■17章は「Cucumberの紹介」とあります。

Cucumber= Cucumberフィーチャー + Cucumberコマンド + ステップ定義
Cucumberフィーチャー = タイトル + 自由形式のナラティブ + いくつかのシナリオ
シナリオ = 任意の数のステップ

いくつかのポイントが説明されています。
・フィーチャのタイトルは短く簡潔に
・ナラティブはConnextraフォーマットを用いて記述しましょう
As a <role>
I want <feature>
So that <business value>
↓ 日本語で書くと
<だれだれ>が
<なになに>したいので
<なぜなら>これこれこういうことをしたいからだ
のようになります。うーん。。

Cucumberのファイルの頭に
#language: ja
と記述するとCucumberが日本語でも記述できます。もともとが英語なのでどうしても不自然ではありますがそれでも日本語で記述できるのはありがたいことです。対応する日本語訳は次のようにするとヘルプを見ることができます。
cucumber –i18n ja

・シナリオは成功するシナリオ(ハッピーパス)から書き始めて、いくつかの特異なケースを追加していきましょう。
・シナリオに対し、ステップを追加していきます。そのとき
Given、When、Then、And、But
で始まるステップキーワードを用います。日本語だと
前提、もし、ならば、かつ、しかし
となります。

・この時点でcucumberを実行するとステップのコードが出力されるのでそれを利用して、ステップファイルを作成しますが、それについては後で説明するとのことです。
・ケースバイケースでステップを一つ一つ細かく書いたり(命令型)、ざっくり書いたり(宣言型)しましょう。
・シナリオが多い場合はfeaturesディレクトリの中に任意のフォルダに分けてfeaturesファイルを整理しましょう。
・タグを活用しましょう
シナリオにタグをつけると後で、そのシナリオだけ実行したり、させなかったりできます。

■18章ではCucumberについてのより詳しい説明がされます。
シナリオに定義されているステップの中で、ステップの内容が定義されていないと、cucumberを実行した際に定義すべきコードが出力されますので、それをfeatures/step_defenitions/の中の任意のファイルに定義します。定義は正規表現になっており、キャプチャグループが引数として扱われます。正規表現そのものを書くことは少ないですが、すこしでも使ったことがないと理解が難しいかもしれません。

使ったことがない人へのヒントとしては「/」で始まって「/」で終わる。「/^」が文頭で「$/」が文末。「([^”]*)」というのは簡単にいう「なんらかの文字」という意味です。この()カッコでくくられたものがキャプチャグループです。それでそこにマッチした文字列が引数となりますよ。と。

RSpecと同じようにフックもあって、タグごとに別のフックを付けられたりすることも説明されています。
カスタマイズはWorldオブジェクトを使います。

ステップ定義の中で別のステップを呼び出せる説明されています。たとえばさまざまなログインをまとめて定義したいとき。

When /^I am logged in as admin$/ do
When I am logged in as “admin”
end
When /^I am logged in as “([^”]*)”$/ do |user_role|
end

とするといいらしいです。別のステップを呼び出すときにそのステップに引数を渡す場合「”」はエスケープしましょう。

When /^I am logged in as “([^”]*)”$/ do |user_role|
When “The email is \”#{user_role}\”@example.com”
end

ステップ内のテーブルを用いて、まとめて複数のテストをしたり、初期設定であらかじめデータを作っておくようなテストをしたりできます。このことははじめのほうの章で簡単なアプリケーションを作ったときに体験しました。

17章と18章はCucumberのざっとした概要になっており、前の章で簡単なアプリケーションを作成するときに使ったテクニックのおさらい+もうちょっと突っ込んだ内容になっています。Cucumberのリファレンスがあればそれを読んだほうがより詳しく知れますし、RSpec同様読んだからといってマスターするまでは至らない程度のざっくり感です。

19章はいよいよRailsではどのようにすればよいのかという一番知りたかった内容が書かれています。

Cucumber1.1.9, capybara1.1.2で日本語を使用するとき便利なステップの定義

たとえばadminしか新規ユーザーを作成できないという仕様で、adminの場合だけユーザー作成画面を表示できることをテストをしたい場合、結果をStep文に含めてしまうと便利なことがあります。

#language: ja

フィーチャ:新規ユーザーの作成
ユーザーとして
新規ユーザー作成画面を表示したい
roleによって新規作成できることを制限したい。

シナリオアウトライン:admin以上であればユーザー新規作成画面を表示できる。
前提 role”<role>”としてログインしている
かつ “ユーザー新規作成画面”へ行く
ならば “<message>”と表示され<boolean>はずだ

例:
| role | message | boolean |
| admin | CanCan::AccessDenied | ない |
| manager | CanCan::AccessDenied | |
| staff | CanCan::AccessDenied | |

上記の場合は表示され(る)か(ない)が入るので、ステップ定義で

ならば /^”([^”]*)”と表示されるはずだ$/ do |message|
page.should have_content(message)
end
ならば /^”([^”]*)”と表示されないはずだ$/ do |message|
page.should_not have_content(message)
end

とすると日本語に結果を含めることができてとてもわかりやすくテストが実装できます。

ちなみにユーザー関係の実装はDeviseを用い、roleによる権限はcancanを用いました。上記の例ではCanCan::AccessDeniedが表示されるかどうかをテストしていて、adminの場合は拒否されないので表示されないことが確認できます。