RSPEC::RAILS介紹(翻譯)

想有一下RSPec來作BDD開發,地發現中文資料太少了,無耐只能本身去主頁上看資料,作爲愛國者,俺的英文真爛得不成,不過翻完了,發出來你們樂一樂吧。shell

 

Spec::rails
---------------------------
一個將RSpec引入Rails的Rails插件
特色:
1. 可使用RSpec獨立的測試models,views,controllers和heplers
2. 整合了具夾(fixture)的載入
3. 爲models和controllers特別製做的生成器,能夠生成指定的測試RSpec文件來代替原來rails默認生成的tests文件。
4. 增長了不少易讀的匹配器
願景:
  對那些剛認識TDD這個概念的人來講,rails的測試支持是一個大的飛躍。弄好這些測試就至關的棒了,由於這樣的rails程序一般會比沒有測試支持的rails程序要容易維護的多。
  對於咱們這些經歷了TDD到如今的BDD的人來講,還必須考慮在現有支持上那些spec之間依賴性的問題。爲此,RSpec支持4種規範。這主要啓發於Test::Rails,這個zenTest內置rails框架。
  咱們還創建良好的mocking和stubbing的支持,以助於打破那些不一樣關聯間的依賴關係。數據庫

不一樣類型的Example Groups:
-------------------------------------------
對以下示例的spec類型,Spec::Rails有各自不一樣的ExampleGroups子類來支持:ruby

Model Examples
這個和rails內置的單元測試工具相同。諷剌的是(對那些傳統的TDD'er),咱們認爲這些只是與數據庫相關的(言下之意,rails內置的test只是提供了數據庫相關的測試)。
詳細示例session

Controller Examples
除了不能真的給你轉向views外,這和你在rails裏作功能測試差很少。並且若是你喜歡,你也能夠強制它轉向一個view。你能夠設置預期的模板,以代替設置預期轉向的頁面。
詳細示例app

view Examples
這是rails功能測試的別一部分。View spec可讓你創建設置指定(感謝ZenTest)
詳細示例框架

Helper示例
你能夠直接測試你heplers裏的指定方法。
詳細示例dom

Fixtures
--------------------------------
你能夠在你任何的specs中使用fixture,如model,view,controller或helper,均可以。若是你想在全局中使用fixture,你能夠在spec/spec_helper.rb設置。看下面的例子:ide

命名約定:
爲了明確和一致,RSpec在目錄和rake任務上使用和Rails內置測試模塊稍微不一樣的命名約定
project
  |
  +--app
  |
  +--...
  |
  +--spec
      |
      +-- spec_helper.rb
      |
      +-- controllers
      |
      +-- helpers
      |
      +-- models
      |
      +-- views
Rake任務也對應的命名函數

Models
---------------------
Model的spec在SRAILS_ROOT/spec/models/目錄中,並提供對fixtures的支持工具

Expectations
---------------------
Model樣板支持以下的自定義Expectations
詳見:Spec::Rails::Expectations
Records
Model.should have(:no).records
Model.should have(1).record
Model.should have(3).records

這個比Model.find(:all).length.should == 3.要簡略一些

Error
model.should have(:no).errors_on(:attribute)
model.should have(1).error_on(:attribute)
model.should have(3).errors_on(:attribute)

Controllers
-----------------------------
Controllers的spec在$RAILS_ROOT/spec/controllers/下
相對Test::Unit,Spec::Rails不須要在setup方法中初始化controller。取而代之的是把controller類傳給describe方法。Spec::Rails會自動給你實例化一個controller,在Examples中你能夠直接訪問該controller的方法

與views獨立開來
-----------------------------
默認狀況下,Spec::Rails將你的Controller actions與相關的views獨立開來。這就讓你能夠在尚未views的時候測試你的controllers,並在當views出錯的時候保持這些(controller的)spec結果。

整合views
------------------------------
若是你要整合views的測試功能(在不少的功能測試中),你能夠在代碼中加入「integrate_views」
describe ArticlesController do
  integrate_views
  ...
end
整合後,你可使用views中使用才能使用的Expectations。詳見views Examples

與數據庫分離
-----------------------------
咱們強烈建議您使用RSpec的mocking/stubbing框架來攔截類級的調用,如:find、:create甚至:new,從而引入mock實例來代替事實的active_record實例 。
這允許你的specs專一於controller所處理的事而不用擔憂那些複雜的驗證和關聯,這些驗證和關聯spec
會在Model Examples中去處理。
account = mock_model(Account)
Account.should_receive(:find).with("37").and_return(account)

account = mock_model(Account)
Account.stub!(:find).and_return(account)
Mocks和Stubs框架詳細信息詳見其文檔。

Response Expectations
----------------------------
  這個Expectations在分離模式或整合模式中都能使用。詳見Spec::Rails::Expectations。
Response.should be_success
  當返回200狀態,測試才能經過。注:分離模式下,這也返回真,因此它的用處不大,但起碼你的specs不會終止。
  response.should be_success
  response.should be_redirect
  返回300-399狀態時經過。
  response.should be_redirect
  response.should render_template
  get 'some_action'
  response.should render_template("path/to/template/for/action")
  response.should have_text
  get 'some_action'
  response.should have_text("expected text")
  response.should redirect_to
  get 'some_action'
  response.should redirect_to(:action => 'other_action')
  還支持以下的格式:
  response.should redirect_to(:action => 'other_action')
  response.should redirect_to('path/to/local/redirect')
  response.should redirect_to('http://test.host/some_controller/some_action')
  response.should redirect_to('http://some.other.domain.com')
  assigns, flash and session
  使用以下方法訪問 assigns, flash 和session.
  assigns[:key]
  flash[:key]
  session[:key]
Routing Expectations(路由Expectations)
--------------------------------
驗證經過路由來得到的地址
route_for(:controller => "hello", :action => "world").should == "/hello/world"
驗證路由發送過來的參數
params_from(:get, "/hello/world").should == {:controller => "hello", :action => "world"}

Views
-----------------------------
  View Examples位於$RAILS_ROOT/spec/views/。
  Spec::Rails支持徹底從他們controllers分離出的views測試。
  這讓你能夠在沒有controllers或是相關acitons被開發以前的時候測試和寫你的views。這也意味着controllers中引入的bugs並不會使views的測試用例失敗。
  正如介紹中說有,這是一個很大的好處,可是他們將controllers和他們的views關互產生的Bugs給隱藏起來了。咱們強烈建議將這些獨立的views測試與高層次的集成測試結合起來,最好使用Cucumber。
  注:Cucumber是一個BDD(BehaviourDrivenDevelopment)工具。
  Spec::Rails::Expectations中還提供了幾個可用的函數。
 
Conveniences
-------------------------------
assigns
  使用assigns[:key]來給view中的實例變量賦值。咱們推薦您這裏使用mock框架,而不是使用真實的model對象,這樣可使view的spec從models的變動中獨立開來。
    # example
 article = mock_model(Article)
 article.should_receive(:author).and_return("Joe")
 article.should_receive(:text).and_return("this is the text of the article")
 assigns[:article] = article
 assigns[:articles] = [article]
 
 # template
 <% for article in @articles -%>
 <!-- etc -->
    flash,params和session
  使用flash[:key],params[:key] 和session[:key]來給view example中的值賦值。
    # example
 flash[:notice] = "Message in flash"
 params[:account_id] = "1234"
 session[:user_id] = "5678"
 
 # template
 <%= flash[:notice] %>
 <%= params[:account_id] %>
 <%= session[:user_id] %>

Examples支持下面的自定義expectations
----------------------
  Spec::Rails的view Examples支持下面的自定義expectations
  response.shoud have_tag
  這個覆蓋了assert_select,並能夠在集成模式下的全部view examples和controller Examples均可以使用。
    response.should have_tag('div') #若是有div標記則經過
 response.should have_tag('div#interesting_div')
 response.should have_tag('div', 'expected content')
 response.should have_tag('div', /regexp matching expected content/)
 response.should have_tag('form[action=?]', things_path)
 response.should have_tag("input[type=?][checked=?]", 'checkbox', 'checked')
 response.should have_tag('ul') do
   with_tag('li', 'list item 1')
   with_tag('li', 'list item 2')
   with_tag('li', 'list item 3')
 end
  注:任何的hash值均可以是Strings或regexps,並獲得相應的評價。
 response[:capture].should have_tag
  這個方法能夠訪問那些被content_for捕獲的內容。
  1.example
    response[:sidebar].should have_tag(‘div’)
  2.template
    <% content_for :sidebar do %>
   Sidebar content here
 <% end %>
Mocking與stubbing helpers
  若是你但願使用mock或stub的helper方法,這些能夠在template對象中完成:
  template.should_receive(:current_user).and_return(mock("user"))

Helpers
----------------------------------------
  Helper Examples在$RAILS_ROOT/spec/helpers/中
  寫helpers的specs很容易,只要告訴ExampleGrouphelper的名字就能夠了
   describe RegistrationHelper do
   ...
 end
  這將會在ExampleGroup中獲得一個包含了這個helper的對象
Conveniences
---------------------
assigns
  使用assigns[:key]來在包含了這個helper的view中給實例變量賦值。詳見上面的鴿子。

writing
---------------------------
  使用Spec::Rails寫Examples介紹
 
  Spec::Rails支持4種不一樣類型的可招執examples
  1.Models Examples
  2.View Examples
  3.Controllor Examples
  4.Helper Examples
  使用這些各專門ExampleGroup子類可讓你訪問適當的服務和方法。他們被放在各自相應的目錄中,並以*_spec.rb的明顯方法標註出來:
    spec/controllers/**/*_spec.rb
 spec/helpers/**/*_spec.rb
 spec/models/**/*_spec.rb
 spec/views/**/*_spec.rb
  警告:若是你沒有遵照這些約定,那能夠得不到正確的ExampleGroup子類。若是你更喜歡無論這些約定,那你也能夠經過傳遞一個hash值給describe方法來得到正確的ExampleGroup子類:
    describe "some model", :type => :model do
   ...
 end
  在:model,:view,:controller和:helper都生效。
 
Generators(生成器)
---------------------------------
Spec::Rails包含了一個生成器,你能夠用來生成models和RESTfulControllers,它和Rails內置的生成器基本同樣。 惟一不一樣的是,他多幫你會在spec目錄下生成一個specs來代替test,還有一個fixtures用來提供測試數據。以下例:
ruby script/generate rspec_scaffold purchase order_id:integer created_at:datetime amount:decimal
ruby script/generate rspec_model person
ruby script/generate rspec_controller person

詳細的用法,能夠以上命令不加參數得到其幫助 。

運行
---------------------
標準的spec命令:
 script/spec path/to/directory/with/specs
 script/spec path/to/individual_spec.rb

快速運行模式--drb(推薦)
------------------------
每次運行 都輸入全部的Rails環境變量,spec運行起來就很慢了。爲了加速測試速度,Spec::Rails安裝一個守護進程腳本,用於加載本地Rails應用,並用DRb偵聽傳入的鏈接。

打開一個shell來運行spec服務:
script/spec_server

如今你可使用--drb參數來使用這個功能了。
若是你使用Rake來運行,應該把--drb加給spec/spec.opts文件。

注意到默認狀況下,有的類和modules不要rails從新載入,在spec中也是同樣的。你也能夠修改rails的環境文件中的策略變量來讓rails每次都從新載入他們。詳細rails的文檔。

使用Rake來運行 specs  注意到rake任務不能使用快速Rails_spec命令--就是說只能使用標準的spec。同時咱們注意到它預設的都是以_spec結尾的文件,因此你必須聽從以下的約定。    注意到你能夠經過編輯sepc/spec.opts文檔來配置傳給RSpec的選項。  那運行全部的spec(包括plugins)的代碼是:    rake spec rake spec:app  包括plugins在內的specs:    rake spec:all  你也可單獨運行 models、controller,view,helper或是plugin的specs:    rake spec:models rake spec:controllers rake spec:views rake spec:helpers rake spec:plugins  查看rake中全部的RSpec任務:    rake --tasks spec

相關文章
相關標籤/搜索