CucumberとWebratをRailsで使って、さらにautotestで動かしてGrowlで通知する
今流行りつつある話題のCucumberとWebratをRailsで使ってみました。
CucumberとWebratなんぞやという人はid:moroさんの「 Cucumberがアツい」が参考になります。
今回やったこと
- RailsにCucumberを入れてみた
- Featureの予約語を日本語にして動かしてみた
- Cucumberをautotestでも動くようにしてみた
- autotestの結果をGrowlに通知するようにしてみた
参考サイト
上記のCucumberがアツい
Cucumberのgithub
必要なパッケージのインストール
以下のgemが必要みたいなので、まだインストールしていない場合はインストールします。
$sudo gem install rspec rspec-rails cucumber webrat term-ansicolor treetop diff-lcs nokogiri
CucumberをRailsで使えるようにする
script/generateを使ってcucumberを動かすのに必要なファイルを生成します。
なお、今回はRSpecも併用するつもりなので一緒に生成しちゃいます。
$ruby script/generate cucumber $ruby script/generate rspec
scaffoldを使ってappと一緒にspecとteatureを自動生成
今回は一から作らずに自動生成で手抜きをします。
$ruby script/generate rspec_scaffold Group name:string about:text $ruby script/generate feature Group name:string about:text $rake db:migrate
生成したfeatureを動かしてみる
cucumberコマンドかrakeで動かせるみたいなのでcucumberコマンドでfeatureを動かしてみる
$cucumber features Feature: Manage groups # features/manage_groups.feature In order to [goal] [stakeholder] wants [behaviour] Scenario: Register new group # features/manage_groups.feature:6 Given I am on the new group page # features/step_definitions/group_steps.rb:1 When I fill in "Name" with "name 1" # features/step_definitions/webrat_steps.rb:18 And I fill in "About" with "about 1" # features/step_definitions/webrat_steps.rb:18 And I press "Create" # features/step_definitions/webrat_steps.rb:10 Then I should see "name 1" # features/step_definitions/webrat_steps.rb:89 And I should see "about 1" # features/step_definitions/webrat_steps.rb:89 Scenario: Delete group # features/manage_groups.feature:14 Given the following groups: # features/step_definitions/group_steps.rb:5 When I delete the 3rd group # features/step_definitions/group_steps.rb:9 Then I should see the following groups: # features/step_definitions/group_steps.rb:16 2 scenarios 9 steps passed
うごいた!!
featureの予約語を日本語にして動かしてみる
角谷さんのコミットのおかげでfeatureの予約後を以下のように日本語で書けるしい。
- Feature → フィーチャ
- Scenario → シナリオ
- Given → 前提
- When → もし
- And → かつ
- Then → ならば
素敵なので早速やってみた。
以下が自動生成したfeature
Feature: Manage groups In order to [goal] [stakeholder] wants [behaviour] Scenario: Register new groups Given I am on the new groups page When I fill in "Name" with "name 1" And I fill in "About" with "about 1" And I press "Create" Then I should see "name 1" And I should see "about 1" Scenario: Delete groups Given the following groups: |name|about| |name 1|about 1| |name 2|about 2| |name 3|about 3| |name 4|about 4| When I delete the 3rd groups Then I should see the following groups: |name|about| |name 1|about 1| |name 2|about 2| |name 4|about 4|
で、以下が予約後を日本語に直したもの
フィーチャ: Manage groups In order to [goal] [stakeholder] wants [behaviour] シナリオ: Register new group 前提 I am on the new group page もし I fill in "Name" with "name 1" かつ I fill in "About" with "about 1" かつ I press "Create" ならば I should see "name 1" かつ I should see "about 1" シナリオ: Delete group 前提 the following groups: |name|about| |name 1|about 1| |name 2|about 2| |name 3|about 3| |name 4|about 4| もし I delete the 3rd group ならば I should see the following groups: |name|about| |name 1|about 1| |name 2|about 2| |name 4|about 4|
で早速動かしてみたけど以下のようにシナリオの数が0になっている。
$cucumber features 0 scenarios
日本語で動かす指定をしなきゃいけないのかな?と思ってcucumber -hでヘルプをみてみると-lでLANGを指定できるみたい。
$cucumber -h Usage: cucumber [options] [[FILE[:LINE[:LINE]*]] | [FILES|DIRS]] Examples: cucumber examples/i18n/en/features cucumber --language it examples/i18n/it/features/somma.feature:6:98:113 -r, --require LIBRARY|DIR Require files before executing the features. If this option is not specified, all *.rb files that are siblings or below the features will be autorequired This option can be specified multiple times. -s, --scenario SCENARIO Only execute the scenario with the given name. If this option is given more than once, run all the specified scenarios. -l, --language LANG Specify language for features (Default: en) Available languages: ar, cy, da, de, en, en-lol, en-tx, es, et, fr, id, it, ja, ko, lt, nl, no, pl, pt, ro, ro2, ru, se, zh-CN Look at /opt/local/lib/ruby/gems/1.8/gems/cucumber-0.1.16/lib/cucumber/languages.yml for keywords -f, --format FORMAT How to format features (Default: pretty) Available formats: pretty, profile, progress, html, autotest You can also provide your own formatter classes as long as they have been previously required using --require or if they are in the folder structure such that cucumber will require them automatically. This option can be specified multiple times. -o, --out FILE Write output to a file instead of @out_stream. This option can be specified multiple times, and applies to the previously specified --format. -c, --[no-]color Use ANSI color in the output, if formatters use it. If these options are given multiple times, the last one is used. If neither --color or --no-color is given cucumber decides based on your platform and the output destination -e, --exclude PATTERN Don't run features matching a pattern -p, --profile PROFILE Pull commandline arguments from cucumber.yml. -d, --dry-run Invokes formatters without executing the steps. -n, --no-source Don't show the file and line of the step definition with the steps. -i, --no-snippets Don't show the snippets for pending steps -q, --quiet Don't show any development aid information -b, --backtrace Show full backtrace for all errors -v, --verbose Show the files and features loaded --version Show version --help You're looking at it
とりあえずcucumber features -l jaをやってみると動いた!!
$cucumber features -l ja フィーチャ: Manage groups # features/manage_groups.feature In order to [goal] [stakeholder] wants [behaviour] シナリオ: Register new group # features/manage_groups.feature:6 前提 I am on the new group page # features/step_definitions/group_steps.rb:1 もし I fill in "Name" with "name 1" # features/step_definitions/webrat_steps.rb:18 かつ I fill in "About" with "about 1" # features/step_definitions/webrat_steps.rb:18 かつ I press "Create" # features/step_definitions/webrat_steps.rb:10 ならば I should see "name 1" # features/step_definitions/webrat_steps.rb:89 かつ I should see "about 1" # features/step_definitions/webrat_steps.rb:89 シナリオ: Delete group # features/manage_groups.feature:14 前提 the following groups: # features/step_definitions/group_steps.rb:5 もし I delete the 3rd group # features/step_definitions/group_steps.rb:9 ならば I should see the following groups: # features/step_definitions/group_steps.rb:16 2 scenarios 9 steps passed
autotestでfeatureを動かす
githubのwikiによるとautotestと組み合わせて動かせるみたいなので次はその設定をやってみる。
と思ったら以下のコマンド一発で動くと書いてある。
$ AUTOFEATURE=true autospec
.bash_profileとかに
export AUTOFEATURE=true
とか書いておくとautospecコマンドだけでfeatureも動くみたい。
私はMacだけどもしWindowsなら環境変数にセットかな?(たぶん)
だだしここでも英語のままだと動くけど、日本語のfeatureは動かなかったのでどっかで教えてあげないといけないみたいです。
あと英語のfeatureをautotestで動かしてみて思ったけど、all-goodだとテスト数とかでないみたいっすね。
この後、Growlでテストの結果を通知したいんだけどこのままじゃあんまりうれしくないんで毎回いろんな情報を出すように変更したいな〜と思いながら四苦八苦。。。
ソースとか見てみると素っ気ない情報しかでないときはautotest-allを通っていて出力フォーマットがprogressになっているからだと判明。
githubのwikiとソースを見るとcucumber.ymlを作ってcucumberコマンドに渡す引数を変更できるっぽいことが書いてる。
という訳でcucumber.ymlを作成
touch ${RAILS_ROOT}/cucumber.yml
で以下のように書く
autotest: features --f pretty --l ja autotest-all: features --f pretty --l ja
これで日本語のfeatureが使えるようになって、かつ出力がdefaultと同じようになった。
Growlでautotestの結果を通知する
これまでの設定で出力もいい感じになったので、autotestの結果をGrowlで通知するように設定
~/.autotestに以下のように記述
require "autotest/redgreen" module Autotest::Growl IMG_OK = '/Developer/Examples/Carbon/Dial/English.lproj/rotate_knob_select.tiff' #適当に使いたい画像のパスに変更する IMG_NG = "/Applications/Mail.app/Contents/Resources/Caution.tiff" #適当に使いたい画像のパスに変更する def self.growl title, msg, img="~/.rails_ok.png", pri=0 title += " in #{Dir.pwd}" msg += " at #{Time.now}" system "growlnotify -n autotest -H localhost --image #{img} -p #{pri} -m #{msg.inspect} #{title}" end Autotest.add_hook :initialize do |at| # Ignore files in tmp/ at.add_exception %r%^\./tmp% end #for RSpec Autotest.add_hook :ran_command do |at| result = [at.results].flatten.join("\n") @result_examples = result.slice(/(\d+)\s+examples?/).to_i @result_tests = result.slice(/(\d+)\s+tests?/).to_i @result_failures = result.slice(/(\d+)\s+failures?/).to_i @result_errors = result.slice(/(\d+)\s+errors?/).to_i end #for Cucumber Autotest.add_hook :ran_features do |at| result = [at.results].flatten.join("\n") @result_scenario = result.slice(/(\d+)\s+scenario?/).to_i @result_passed = result.slice(/(\d+)\s+(step|steps)\spassed?/).to_i @result_skip = result.slice(/(\d+)\s+(step|steps)\sskipped?/).to_i @result_pending = result.slice(/(\d+)\s+(step|steps)\spending?/).to_i @result_failed = result.slice(/(\d+)\s+(step|steps)\sfailed?/).to_i end Autotest.add_hook :waiting do if @result_failures + @result_errors + @result_skip + @result_pending + @result_failed> 0 growl "Tests Failed", "RSpec #{@result_failures} failures #{@result_errors} errors Cucumber #{@result_failed} failed #{@result_pending} pending #{@result_skip} skip ", IMG_NG, 2 else growl "Tests Passed", "#{@result_tests + @result_examples + @result_passed} tests", IMG_OK end end end
毎回RSpecとCucumberのテストを計2回通知するとうるさかったのでRSpecとCucumberのテスト結果をインスタンス変数に持たせてすべてのテストが終わってwaitingになったところで通知するようにしてみました。
これで快適なテスト環境が出来た気がするので明日にでもid:moroさんの「Webratがスゴい(続:Cucumberがアツい)」を参考にfeatureの全日本語化をためしてみます。