RSPEC::RAILS介绍(转载分享)
2013-01-30 11:49
176 查看
这篇博文在都定网上看到的,但是豆丁比较坑,要10元钱才好下载。下载共享出来与大家分享,如有版权问题,请与我联系。
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的支持,以助于打破那些不同关联间的依赖关系。
不同类型的ExampleGroups:
-------------------------------------------
对如下示例的spec类型,Spec::Rails有各自不同的ExampleGroups子类来支持:
ModelExamples
这个和rails内置的单元测试工具相同。讽剌的是(对那些传统的TDD'er),我们认为这些只是与数据库相关的(言下之意,rails内置的test只是提供了数据库相关的测试)。
详细示例
ControllerExamples
除了不能真的给你转向views外,这和你在rails里做功能测试差不多。而且如果你喜欢,你也可以强制它转向一个view。你可以设置预期的模板,以代替设置预期转向的页面。
详细示例
viewExamples
这是rails功能测试的别一部分。Viewspec可以让你建立设置指定(感谢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.shouldhave(:no).records
Model.should have(1).record
Model.shouldhave(3).records
这个比Model.find(:all).length.should==
3.要简略一些
Error
model.shouldhave(:no).errors_on(:attribute)
model.shouldhave(1).error_on(:attribute)
model.shouldhave(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将你的Controlleractions与相关的views独立开来。这就让你可以在还没有views的时候测试你的controllers,并在当views出错的时候保持这些(controller的)spec结果。
整合views
------------------------------
如果你要整合views的测试功能(在很多的功能测试中),你可以在代码中加入“integrate_views”
describeArticlesController do
integrate_views
...
end
整合后,你可以使用views中使用才能使用的Expectations。详见viewsExamples
与数据库分离
-----------------------------
我们强烈建议您使用RSpec的mocking/stubbing框架来拦截类级的调用,如:find、:create甚至:new,从而引入mock实例来代替事实的active_record实例。
这容许你的specs专注于controller所处理的事而不用担心那些复杂的验证和关联,这些验证和关联spec
会在ModelExamples中去处理。
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框架详细信息详见其文档。
ResponseExpectations
----------------------------
这个Expectations在分离模式或整合模式中都能使用。详见Spec::Rails::Expectations。
Response.shouldbe_success
当返回200状态,测试才能通过。注:分离模式下,这也返回真,所以它的用处不大,但起码你的specs不会终止。
response.should be_success
response.should be_redirect
返回300-399状态时通过。
response.should be_redirect
response.shouldrender_template
get 'some_action'
response.shouldrender_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.shouldredirect_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]
RoutingExpectations(路由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("thisis 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]来给viewexample中的值赋值。
# example
flash[:notice] = "Message inflash"
params[:account_id] = "1234"
session[:user_id]= "5678"
# template
<%=flash[:notice] %>
<%= params[:account_id] %>
<%=session[:user_id] %>
Examples支持下面的自定义expectations
----------------------
Spec::Rails的viewExamples支持下面的自定义expectations
response.shoud have_tag
这个覆盖了assert_select,并可以在集成模式下的所有viewexamples和controllerExamples都可以使用。
response.should have_tag('div') #如果有div标记则通过
response.shouldhave_tag('div#interesting_div')
response.shouldhave_tag('div', 'expected content')
response.shouldhave_tag('div', /regexp matching expected content/)
response.shouldhave_tag('form[action=?]', things_path)
response.shouldhave_tag("input[type=?][checked=?]", 'checkbox','checked')
response.should have_tag('ul') do
with_tag('li', 'list item 1')
with_tag('li', 'listitem 2')
with_tag('li', 'list item 3')
end
注:任何的hash值都可以是Strings或regexps,并得到相应的评价。
response[:capture].shouldhave_tag
这个方法可以访问那些被content_for捕获的内容。
1.example
response[:sidebar].shouldhave_tag(‘div’)
2.template
<%content_for :sidebar do %>
Sidebar contenthere
<% end %>
Mocking与stubbinghelpers
如果你希望使用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.ControllorExamples
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用来提供测试数据。如下例:
rubyscript/generate rspec_scaffold purchase order_id:integercreated_at:datetime amount:decimal
ruby script/generaterspec_model person
ruby script/generate rspec_controller person
详细的用法,可以以上命令不加参数获得其帮助。
运行
---------------------
标准的spec命令:
script/specpath/to/directory/with/specs
script/specpath/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
rakespec:views
rake spec:helpers
rake spec:plugins
查看rake中所有的RSpec任务:
rake --tasks spec
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的支持,以助于打破那些不同关联间的依赖关系。
不同类型的ExampleGroups:
-------------------------------------------
对如下示例的spec类型,Spec::Rails有各自不同的ExampleGroups子类来支持:
ModelExamples
这个和rails内置的单元测试工具相同。讽剌的是(对那些传统的TDD'er),我们认为这些只是与数据库相关的(言下之意,rails内置的test只是提供了数据库相关的测试)。
详细示例
ControllerExamples
除了不能真的给你转向views外,这和你在rails里做功能测试差不多。而且如果你喜欢,你也可以强制它转向一个view。你可以设置预期的模板,以代替设置预期转向的页面。
详细示例
viewExamples
这是rails功能测试的别一部分。Viewspec可以让你建立设置指定(感谢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.shouldhave(:no).records
Model.should have(1).record
Model.shouldhave(3).records
这个比Model.find(:all).length.should==
3.要简略一些
Error
model.shouldhave(:no).errors_on(:attribute)
model.shouldhave(1).error_on(:attribute)
model.shouldhave(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将你的Controlleractions与相关的views独立开来。这就让你可以在还没有views的时候测试你的controllers,并在当views出错的时候保持这些(controller的)spec结果。
整合views
------------------------------
如果你要整合views的测试功能(在很多的功能测试中),你可以在代码中加入“integrate_views”
describeArticlesController do
integrate_views
...
end
整合后,你可以使用views中使用才能使用的Expectations。详见viewsExamples
与数据库分离
-----------------------------
我们强烈建议您使用RSpec的mocking/stubbing框架来拦截类级的调用,如:find、:create甚至:new,从而引入mock实例来代替事实的active_record实例。
这容许你的specs专注于controller所处理的事而不用担心那些复杂的验证和关联,这些验证和关联spec
会在ModelExamples中去处理。
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框架详细信息详见其文档。
ResponseExpectations
----------------------------
这个Expectations在分离模式或整合模式中都能使用。详见Spec::Rails::Expectations。
Response.shouldbe_success
当返回200状态,测试才能通过。注:分离模式下,这也返回真,所以它的用处不大,但起码你的specs不会终止。
response.should be_success
response.should be_redirect
返回300-399状态时通过。
response.should be_redirect
response.shouldrender_template
get 'some_action'
response.shouldrender_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.shouldredirect_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]
RoutingExpectations(路由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("thisis 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]来给viewexample中的值赋值。
# example
flash[:notice] = "Message inflash"
params[:account_id] = "1234"
session[:user_id]= "5678"
# template
<%=flash[:notice] %>
<%= params[:account_id] %>
<%=session[:user_id] %>
Examples支持下面的自定义expectations
----------------------
Spec::Rails的viewExamples支持下面的自定义expectations
response.shoud have_tag
这个覆盖了assert_select,并可以在集成模式下的所有viewexamples和controllerExamples都可以使用。
response.should have_tag('div') #如果有div标记则通过
response.shouldhave_tag('div#interesting_div')
response.shouldhave_tag('div', 'expected content')
response.shouldhave_tag('div', /regexp matching expected content/)
response.shouldhave_tag('form[action=?]', things_path)
response.shouldhave_tag("input[type=?][checked=?]", 'checkbox','checked')
response.should have_tag('ul') do
with_tag('li', 'list item 1')
with_tag('li', 'listitem 2')
with_tag('li', 'list item 3')
end
注:任何的hash值都可以是Strings或regexps,并得到相应的评价。
response[:capture].shouldhave_tag
这个方法可以访问那些被content_for捕获的内容。
1.example
response[:sidebar].shouldhave_tag(‘div’)
2.template
<%content_for :sidebar do %>
Sidebar contenthere
<% end %>
Mocking与stubbinghelpers
如果你希望使用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.ControllorExamples
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用来提供测试数据。如下例:
rubyscript/generate rspec_scaffold purchase order_id:integercreated_at:datetime amount:decimal
ruby script/generaterspec_model person
ruby script/generate rspec_controller person
详细的用法,可以以上命令不加参数获得其帮助。
运行
---------------------
标准的spec命令:
script/specpath/to/directory/with/specs
script/specpath/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
rakespec:views
rake spec:helpers
rake spec:plugins
查看rake中所有的RSpec任务:
rake --tasks spec
相关文章推荐
- 转载分享:Android APP二次打包操作步骤介绍
- 【转载】Kafka介绍及升级经验分享
- 转载一篇比较详细介绍rails routes的文章
- 转载分享:Android APP二次打包操作步骤介绍
- Unity3d 引擎原理详细介绍、Unity3D引擎架构设计- zhibolife(转载分享)
- C# 特性(Attribute)详细介绍(转载)
- 介绍分享几款免费的在线Web文件管理器
- Rspec在Rails项目中的使用
- 转载_嵌入式实时系统性能和实现介绍
- 一个公司的团队组织介绍。(转载)
- Ruby on Rails调试经验分享
- 转载: CSS Hack 兼容浏览器经验分享
- (转载)cocos2d-X学习之主要类介绍:动作:CCAction
- iOS开发UI篇—UIWindow简单介绍(转载)
- (转载)VS2010/MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)
- [转载]C#自定义事件的步骤介绍
- [转载]十年编程经验凝结 与新人们分享
- Rails 4.0 bundle exec rspec spec/requests/xxx 测试失败的解决
- Diffuse: 文件工具介绍[转载]
- 转载:标准模板库(STL)介绍