RSPEC::RAILS介绍(翻译)

想有一下RSPec来做BDD开发,地发现中文资料太少了,无耐只能自己去主页上看资料,做为爱国者,俺的英文真烂得不成,不过翻完了,发出来大家乐一乐吧。

 

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子类来支持:

Model Examples
这个和rails内置的单元测试工具相同。讽剌的是(对那些传统的TDD'er),我们认为这些只是与数据库相关的(言下之意,rails内置的test只是提供了数据库相关的测试)。
详细示例

Controller Examples
除了不能真的给你转向views外,这和你在rails里做功能测试差不多。而且如果你喜欢,你也可以强制它转向一个view。你可以设置预期的模板,以代替设置预期转向的页面。
详细示例

view Examples
这是rails功能测试的别一部分。View spec可以让你建立设置指定(感谢ZenTest)
详细示例

Helper示例
你可以直接测试你heplers里的指定方法。
详细示例

Fixtures
--------------------------------
你可以在你任何的specs中使用fixture,如model,view,controller或helper,都可以。如果你想在全局中使用fixture,你可以在spec/spec_helper.rb设置。看下面的例子:

命名约定:
为了明确和一致,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

转载于:https://my.oschina.net/zhao/blog/10544

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值