2008-11-12
Cucumberがアツい
仕事で作っているRailsアプリにCucumberを突っ込んでみました。これは熱い。いやもう十分、お客さんに見せて分かってもらえる気がします。たぶん。もちろん準備は必要だし、受け入れ仕様をすべてお客さんに書いてもらうというのは難しいですけど*1。
とりあえず導入はこちらから。最近はNokogiriが必要です。あとTerminal.appで--no-colorつけずに実行するとTerminal.appがひどいことになるのでiTermお薦めです。
http://github.com/aslakhellesoy/cucumber/wikis/ruby-on-rails
2010-11-10
SEO的に。この記事を書いてから2年、いろんなCucumberの使い方を調べました。そのノウハウを達人出版会にて本にまとめました。よろしければこちらもどうぞ。
http://tatsu-zine.com/books/cuke
使い方
rails部門のtophatenarらしいので(あんまり関係ないけど)Rails前提の話しです。
cucumberプラグインをインストールして、script/generate cucumberすると、Railsをテストするためのいろんなファイルが生成されます。たとえばscript/cucumberに実行スクリプトが入ります。
差しあたり重要なのは以下の二つほど。
- features/support/env.rb
- features/step_definitions/webrat_steps.rb
cucumberの構造
cucumberでは、まずfeatures/hoge.featureという命名規則でfeatureファイルを書きます。これが「自然言語(ぽい)」「プレーンテキスト」で「受け入れ仕様を記述する」ファイルとなります。
たとえば次のようなコマンドで受け入れ仕様のひな形を作ります。
$ ruby script/generate feature Entry
exists features/step_definitions
create features/manage_entries.feature
create features/step_definitions/entry_steps.rb
ここでできたfeatures/manage_entries.featureがfeatureファイルですね。中身はこんなの。
$ cat features/manage_entries.feature
Feature: Manage entries
In order to keep track of entries
A entry mechanic
Should be able to manage several entries
Scenario: Register new entry
Given I am on the new entry page
And I press "Create"
Scenario: Delete entry
Given there are 4 entries
When I delete the first entry
Then there should be 3 entries left
More Examples:
| initial | after |
| 100 | 99 |
| 1 | 0 |
どうみてもプレーンテキストですね。すばらしい。これを実行できるのがCucumberです。
で、どうみてもプレーンテキストなので、このままでは実行できません。これをなんとかして実行するための仕組みがstepsと呼ばれているものです。具体的には features/step_definitions/entry_steps.rb ですね。
$ cat features/step_definitions/entry_steps.rb Given /I am on the new entry page/ do visits "/entries/new" end Given /there are (\d+) entries/ do |n| Entry.transaction do Entry.destroy_all n.to_i.times do |n| Entry.create! :name => "Entry #{n}" end end end When /I delete the first entry/ do visits entries_url clicks_link "Destroy" end Then /there should be (?d+) entries left/ do |n| Entry.count.should == n.to_i response.should have_tag("table tr", n.to_i + 1) # There is a header row too end
ということでfeatureファイルの文言にマッチするような正規表現と、実際のRubyコードが並んでいます。具体的にはインデントレベル2くらいのGivenやAnd、When、Thenの文言に対応しています。
Cucumberは実行時にfeatureファイルを解析し、文言がマッチするstepの処理を実行してテストします。stepは正規表現を使えますので、文章中の一部を動的に取り出すことも出来ます。たとえば "Given there are 4 entries"というfeature内の文言に対し、Given /there are (\d+) entries/ というstepがマッチして、"4"を動的に指定できているイメージが伝わるはず。
で、Given、When、Thenはそれぞれ、前提、処理内容、その結果(に対する検証)、となります。これを上から順に書いていくわけですね。Andは前のstepと同じ事を繰り返します。Thenでは検証をするんですが、検証にはRSpecの語彙(should/should_not)が使えます。
また、このシナリオを日本語で書いてみればこんな感じです。
Scenario: 新しいエントリの登録
前提 I am on the new entry page
かつ I press "Create"
Scenario: エントリの削除
前提 there are 4 entries
もし I delete the first entry
ならば there should be 3 entries left
さらに、"there are 4 entries"とかのところはstepで正規表現で指定してます。そのためstepに次のような定義があれば
Given /^(\d+).? のエントリがある/ do |n| Entry.transaction do Entry.destroy_all n.to_i.times do |n| Entry.create! :name => "Entry #{n}" end end
こう書けます。
Scenario: エントリの削除
前提 4つ のエントリがある
もし I delete the first entry
ならば there should be 3 entries left
こんな感じでstepを充実させていけばOK。
と、ここで終わると面倒なだけじゃんと思うかもしれませんが、意外とテストに書く語彙(=やること)は決まってるじゃないですか。こうExcelでテスト仕様書書いてても。なので、一回つくってしまえば意外と使い回せそうな気がしてます。
で、実はここで書いた「前提」とかは角谷さんの尽力によりそのまま使えます。
http://github.com/aslakhellesoy/cucumber/commit/9291e7c8d1de8189dfda3d2d7318277731fb9c5b
ということでもう少し詳しい使い方はあとで書く。
Railsとの絡み
箇条書きで。
- Railsのテストをするためにwebratを使ってる
- webratでHTMLを検証するためにNokogiri使ってる
- RailsのテストはIntegrationTestのレイヤで。ActionController::Integration::Sessionを使ってます。
- ようはActionController::Dispatcher.dispach から先を検証している
- これをwebratのSessionでくるんで使う感じ。
- IntegrationTestの制約は当然受ける
- fixturesも使えるはず
OpenIDの件はあとで書く、ということで私のTwitterをみてwktkしてた人にはひどいことをしましたよね。ごめんなさい。あとで書きます。
- moroの日記 - Webratがスゴい(続:Cucumberがアツい)
- moroの日記 - Cucumberチーム内勉強会の動画が公開されました
- Rubyとか Illustratorとか SFとか折紙とか - Rails(2.2.2)アプリケ...
- koumiyaの日記 - Cucumber予習
- moroの日記 - Railsテスティング環境2009新春 @仙台Ruby会議01
- [テスト][RSpec][Rails][ruby][cucumber]CucumberとWebratをRailsで...
- koumiyaの日記 - Cucumberでブログシステムの統合テストをする
- yuum3のお仕事日記 - Cucumber にふれてみた
- 常識という迷信 - githubで管理されてる注目プロジェクトのまとめ
- いろいろ備忘録日記 - Cucumberの情報 (ビヘイビア駆動開発, Behav...
- うんたらかんたらRuby - [rails][cucumber]cucumber事始め
- opamp_sandoの日記 ...でいいよね - jewelerでCucumberを使ってみる...
- 1534 http://www.google.co.jp/search?q=Cucumber&lr=lang_ja&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&client=firefox-a
- 1091 http://www.google.co.jp/search?q=Cucumber&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:ja:unofficial&client=firefox-a
- 1008 http://www.google.co.jp/url?sa=t&rct=j&q=cucumber&source=web&cd=2&ved=0CDUQFjAB&url=http://d.hatena.ne.jp/moro/20081112/1226486135&ei=NIRgTpTkLYmKmQXWqajdDQ&usg=AFQjCNFJjnzcrnZdPF2cWdM6MPlhxasVww&sig2=oxISzmPb2jxB7zEYpW5IfA
- 442 https://www.google.co.jp/
- 434 http://www.google.co.jp/search?sourceid=chrome&ie=UTF-8&q=cucumber
- 384 http://d.hatena.ne.jp/amacou/20090127/1233058682
- 364 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CEoQFjAB&url=http://d.hatena.ne.jp/moro/20081112/1226486135&ei=8lpMT6vTEYrnmAWJmaT2Dw&usg=AFQjCNFJjnzcrnZdPF2cWdM6MPlhxasVww&sig2=PKBtP3QWbWlmumcRLGDPVg
- 304 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&ved=0CF4QFjAC&url=http://d.hatena.ne.jp/moro/20081112/1226486135&ei=T4wfT6rGIrGNmQX16aW_Dg&usg=AFQjCNFJjnzcrnZdPF2cWdM6MPlhxasVww&sig2=zpM9Wp8E3OUwvLG1v7TF8w
- 261 http://www.ark-web.jp/sandbox/wiki/redirect.php?url=http://d.hatena.ne.jp/moro/20081112/1226486135
- 228 http://www.google.co.jp/search?aq=f&sourceid=chrome&ie=UTF-8&q=cucumber




