話é¡ã®ãã¹ããã¼ã« Steak ãåå¼·ãã¦ã¿ã
以å Ruby on Railsã®é人 @a_matsuda ã« è¦ãããã ãã¹ããã¼ã« Steak ãç¾å¨éçºä¸ã®ããã¸ã§ã¯ãã§ä½¿ã£ã¦ã¿ããã¨æããåå¼·ãã¦ã¿ã¾ããã
Steakã¨ã¯
Steak 㯠Cucumber åæ§ã« Ruby on Railsãªã©ã®Webã¢ããªã®åãå ¥ããã¹ããç·åãã¹ãã®ãã¼ã«ã§ããCucumberã¯ä»æ§(ãã¹ã)ãèªç¶è¨èªã§è¨è¿°ã§ããã®ã大ããªç¹å¾´ã§ããããSteakã§ã¯RSpecï¼å°ç¨DSLã§è¨è¿°ãã¾ã¾ãã
Cucumberã¯ä»æ§(ãã¹ã)ãèªç¶è¨èªã§æ¸ããã®ã§ãã¦ã¼ã¶ã¼ã«ä»æ§ã確èªãã¦ãããã¨ãä½ã£ã¦ããããã®ãæ大ã®ã¡ãªããã§ããããããã®åãfeature(ä»æ§)ã¨Step(ä»æ§ãããã°ã©ã ãã¤ãªãã³ã¼ã)ã®ï¼ã¤ãè¨è¿°ããå¿ è¦ããéçºã®æéãåããã¾ãã
ããã«æ¯ã¹ã Steak 㯠RSpec (ï¼ Rubyã®ã³ã¼ã) ãªã®ã§ãããã°ã©ãã¼ã«åã£ã¦ã¯ãèªã¿æ¸ãã¯å®¹æã§ãã
åãå
¥ããã¹ããç·åãã¹ãã§ã¯è¡¨ç¤ºçµæ(html) ã確èªããã³ã¼ããå¿
è¦ã«ãªãã¾ããã Steak ã§ã¯ Capybala ã使ã CSSã»ã¬ã¯ã¿ã¼ã§htmlã®è¦ç´ ãæå®ã§ããã®ã§ç°¡æ½ãªè¨è¿°ãåºæ¥ã¾ãã
CSSã»ã¬ã¯ã¿ã¼ã¯ããã¶ã¤ãã¼ã§ã¯ãªãããã°ã©ãã¼ã§ãjQueryçã§ã使ããã¦ããã®ã§ã馴æã¿ã ã¨æãã¾ãã
ã¤ã³ã¹ãã¼ã«
ã¤ã³ã¹ãã¼ã«ã¯ Steak ãã¼ã¸ã«æ¸ããã¦ããããã« bundle (Rails3)ãªãç°¡åã§ãã
1. Gemfileã«ä»¥ä¸ã追å ãã bundle install ãå®è¡
group :test, :development do gem "rspec-rails" gem 'steak' gem 'capybara' gem 'spork' end
2. ããã¸ã§ã¯ãå ã§ä»¥ä¸ã®åæåã³ãã³ãã®å®è¡
$ rails g rspec:install $ rails g steak:install
å¾ã¯ rails generate steak:spec ã³ãã³ã㧠feature(ä»æ§)ãã¡ã¤ã«ãä½ããããã«ã³ã¼ããæ¸ãã¦è¡ãã¾ã
ãã¹ã対象ã®ä½æ
åå¼·ãªã®ã§ç°¡åãªããã°ã©ã ã¨ãããã¨ã§ scaffold ã§åºæ¥ãã³ã¼ãããã¹ããã¦ã¿ãäºã«ãã¾ããã
$ rails new todo_steak -T $ cd todo_steak $ rails g rspec:install $ rails g steak:install $ rails g scaffold todo due:date task:string $ rake db:migrate $ RAILS_ENV=test rake db:migrate $ vi spec/fixtures/todos.yml <= ãã¹ããã¼ã¿ã®ä½æ ----------- todo01: due: 2011-02-18 task: æã¡åãã todo02: due: 2011-02-20 task: éçº ----------- $ rake db:migrate $ RAILS_ENV=test rake db:migrate $ vi app/models/todo.rb <= validation ã®è¿½å ------------ class Todo < ActiveRecord::Base validates_presence_of :task end ------------ $ vi app/controllers/todos_controller.rb ------------ @todos = Todo.all â <= ã½ã¼ãæå® @todos = Todo.order(:due).all ------------
ãã¹ãã³ã¼ã
1. ä¸è¦§è¡¨ç¤ºæ©è½ spec/acceptance/list_feature_spec.rb
require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper') feature "Todoä¸è¦§ã®è¡¨ç¤º" do fixtures :todos scenario "Todoä¸è¦§ã表示ã§ãã" do visit list_page page.should have_css("h1", :text => "Listing todos") page.all("table tr:eq(2) td")[0..1].map{|e| e.text}.should == ["2011-02-18", "æã¡åãã"] page.all("table tr:eq(3) td")[0..1].map{|e| e.text}.should == ["2011-02-20", "éçº"] end end
scenarioã«ä»æ§(ãã¹ã)ãæ¸ãã¾ãã
- vist list_page ã¯ã§istãã¼ã¸ãã¢ã¯ã»ã¹
- list_page 㯠spec/acceptance/support/paths.rb ã§å ·ä½çãªURLãå®ç¾©ãã¦ãã¾ã
module NavigationHelpers def list_page "/todos" end def new_page "/todos/new" end end RSpec.configuration.include NavigationHelpers, :type => :acceptance
- page.should have_css("h1", ⦠ã¯ãã¼ã¸ä¸ã« Listing todos ã¨æ¸ãããh1ã¿ã°ãå¨ããã¨ãæ¤è¨¼ãã¾ã
- 次ã®2è¡ã¯
- ä¸è¦§ãã¼ã¸ã«ã¯ãTodoæ å ±ãtableã¿ã°ã§è¡¨ç¤ºããã¾ãã®ã§ãtableã®2è¡ç®ã3è¡ç®ã«fixture ã§ä¸ããå¤ã表示ããã¦ãããæ¤è¨¼ãã¦ãã¾ã
- CSSã»ã¬ã¯ã¿ã¼ "table tr:eq(2) td"ã¯tableã¿ã°å ã®2çªç®ã®trã¿ã°å ã®å ¨ã¦ã®tdã¿ã°ãé¸æãã¾ã
- é¸æããã tdãã°ã®1çªç®2çªç®ã®å 容(æåå)ãåãåºãããåãRSpec ã® should == ã§æ¤è¨¼ãã¦ãã¾ã
- ãã®é¨åã¯ä½ãcoolãªhelperãå®ç¾©ãã¦ã¹ãã¼ãã«è¨è¿°ãããã§ãã
ãã¹ãã®å®è¡ã¯ RSpec ãªã®ã§ spec ã³ãã³ãã rake spec ã§ãã
2. æ°è¦ä½ææ©è½ spec/acceptance/new_feature_spec.rb
require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper') feature "Todoã®æ°è¦ä½æ" do fixtures :todos scenario "Todoãæ°è¦ä½æã§ãã" do visit new_page within "form" do select "2011", :from => "todo_due_1i" select "February", :from => "todo_due_2i" select "10", :from => "todo_due_3i" fill_in "Task", :with => "ãã¹ã" click_button "Create Todo" end page.should have_css "#notice", :text => "Todo was successfully created." Todo.count.should == 3 Todo.last.due.to_s.should == "2011-02-10" Todo.last.task.should == "ãã¹ã" end scenario "Taskã空ãªãã¨ã©ã¼ã«ãªã" do visit new_page within "form" do select "2011", :from => "todo_due_1i" select "February", :from => "todo_due_2i" select "10", :from => "todo_due_3i" fill_in "Task", :with => "" click_button "Create Todo" end page.should have_content "Task can't be blank" end end
æåã® scenario ã¯æ°è¦ç»é²ãã¼ã¸ã表示ãããã©ã¼ã ã«å ¥åãsubmitãã¿ã³ãæ¼ãã¨æåãRDBã«ãã¼ã¿ãåºæ¥ã¦ããäºãæ¤è¨¼ãã¦ãã¾ãã
- within "form" do ã§formã¿ã°å ãæä½(æ¤è¨¼)対象ã¨ãã¾ã
- select "2011", :from => "todo_due_1i" 㯠id ã todo_due_1i ã®selectã¿ã°ã§ 2011 ãé¸æãã¾ã
- fill_in "Task", :with => "ãã¹ã" 㯠Task ã¨ããã©ãã«ã®inputãã£ã¼ã«ãã« "ãã¹ã"ã¨å ¥åãã¾ããinput ã¿ã°ã®æå®ã¯ id ã name 対å¿ãã label ãªã©ã使ãã¾ã
- click_button "Create Todo" 㧠Create Todo ãã¿ã³ãæ¼ããããã©ã¼ã ã®å¤ãpostããã¾ã
- page.should have_css.... ã¯æåã¡ãã»ã¼ã¸ã表示ããã¦ããäºãæ¤è¨¼ãã¦ãã¾ã
- Todo.ããå§ã¾ã3è¡ã¯Todoãã¼ãã«ã«ãã©ã¼ã ããå ¥åããå¤ã§ã¬ã³ã¼ããåºæ¥ã¦ããäºãæ¤è¨¼ãã¦ãã¾ã
ã¤ãã® scenario ã¯å
¥åã¨ã©ã¼ãã§ãã¯ã®æ¤è¨¼ã§ããTaskãã£ã¼ã«ãã«ä½ãå
¥åããã¦ãªãå ´åã¯ã¨ã©ã¼ã表示ãããäºã確èªãã¦ãã¾ã
è¨è¿°ã¯ãä¸ã¨ã»ã¼åããªã®ã§çç¥ãã¾ãã
Steak ã®ææ³
- Steak ã¯RSpecãªã®ã§ãã¥ã¼ã¬ãã«ã®æ¤è¨¼ãã¢ãã«ã¬ãã«ã®æ¤è¨¼ãåãããã«ãåããã¡ã¤ã«ã«æ¸ããã¯å¬ããã§ã
- RSpecãªã®ã§ spork ã¨çµã¿åãããã¨ãã¹ãã®å®è¡ã¯é«éã§ããéçºæã«ã¯ããã¸ãå¬ããã§ãã
- CSSã»ã¬ã¯ã¿ã¼ã® :eq(n) 㯠jQueryã§ã¯ 0 ããå§ã¾ãã¾ãããCapybara ã§ã¯ 1 ããå§ã¾ãã¾ããåããã¦æ¬²ããã§ãã
- Javascriptãå«ããã¹ãã§ããã¨ãã capybara-envjs ã試ããã®ã§ããããã¹ããã jQueryã®ã³ã¼ãã¯åãã¾ããã§ãããã¾ã éçºéä¸ãããã§ããå°æ¥ã«æå¾ ãã¾ããã !!
ã¨ãããã¨ã§ãä»åã®ããã¸ã§ã¯ãã§ã¯ Steak ã使ã£ã¦ ç·åãã¹ããæ¸ãã¦ã¿ããã¨æãã¾ããããã¸ã§ã¯ããçµãã£ãããã¾ã Steak ã«ä»ãã¦æ¸ãããã¨æãã¾ãã