如何进行高效的Rails单元测试
答案:2 悬赏:60 手机版
解决时间 2021-04-05 23:14
- 提问者网友:沉默的哀伤
- 2021-04-05 01:18
如何进行高效的Rails单元测试
最佳答案
- 五星知识达人网友:千杯敬自由
- 2021-04-05 01:31
第步 安装rspecrspec-rails命令行执行命令:
$ sudo gem install rspec v = 1.3.0
$ sudo gem install rspec-rails v = 1.3.2
安装完进入rails应用所目录运行脚本spec测试框架:
$ script/generate rspec
exists lib/tasks
identical lib/tasks/rspec.rake
identical script/autospec
identical script/spec
exists spec
identical spec/rcov.opts
identical spec/spec.opts
identical spec/spec_helper.rb
第二步 安装factory-girl命令行执行命令:
相关厂商内容
百度研究院高级科家谈规模机器习技术 猫前端发专家鬼道解读Native Web 融合 《深入浅Node.js》作者朴灵主持QCon全栈发专题 知乎联合创始兼 CTO品QCon知名移案例专题 伤筋骨百-型组织转型实例剖析 相关赞助商
全球软件发4月23-25北京敬请期待
$ sudo gem install factory-girl
config/environment/test.rb加入factory-girlgem:
config.gem "factory_girl"
spec/目录增加factories.rb文件用于所预先定义model工厂
第三步 安装autotest命令行执行命令:
$ sudo gem install ZenTest
$ sudo gem install autotest-rails
设置与RSpec集rails应用目录运行命令显示测试用例运行结
RSPEC=true autotest or autospec
自home目录增加.autotest设置所Rails应用autotest插件文件加每应用根目录文件覆盖home目录文件设置autotest插件笔者用plugin:
$ sudo gem install autotest-growl
$ sudo gem install autotest-fsevent
$ sudo gem install redgreen
设置.autotest文件.autotest加入代码
require 'autotest/growl'
require 'autotest/fsevent'
require 'redgreen/autotest'
Autotest.add_hook :initialize do |autotest|
%w{.git .svn .hg .DS_Store ._* vendor tmp log doc}.each do |exception|
autotest.add_exception(exception)
end
end
测试经验安装必要程序库写测试代码本例所应用都Rails 2.3.4发RSpec采用1.3.0版本说明问题我假定需求:判断用户间段内否迟写测试代码都遵循原则关输入输具体实现并测试代码考虑范围内行驱发根据需求我设计absence_at(start_time,end_time)两输入值start_timeend_time及输值类型boolean应测试代码:
describe "User absence or not during [start_time,end_time]" do
before :each do
@user = Factory(:user)
end
it "should return false when user not absence " do
start_time = Time.utc(2010,11,9,12,0,0,0)
end_time = Time.utc(2010,11,9,12,30,0)
@user.absence_at(start_time,end_time).should be_false
end
it "should return true when user absence " do
start_time = Time.utc(2010,11,9,13,0,0,0)
end_time = Time.utc(2010,11,9,13,30,0)
@user.absence_at(start_time,end_time).should be_ture
end
end
测试代码已经完至于absence_at我并关实现要结能让测试代码运行结确测试代码基础胆完代码并根据测试代码结断修改代码直所测试用例通
Stub使用写测试代码首先model始model能与输入输原则吻合容易手初候发现mockstub用任何象都mock并且基础stub些省构造数据麻烦度让笔者觉测试代码美丽步步深入才发现自陷入stub误区引用面例我代码实现:
class User < ActiveRecord::Base
def absence_at(start_time,end_time)
return false if have_connection_or_review?(start_time,end_time)
return (login_absence_at?(start_time,end_time) ? true : false)
end
end
按照初写测试代码思路本存三种情况即需要三用例且调用其两需要进行stub于面测试代码记完兴奋想:写测试代码真趣
before(:each) do
@user = User.new
end
describe "method " do
s = Time.now
e = s + 30.minutes
# example one
it "should be false when user have interaction or review" do
@user.stub!(:have_connection_or_review?).with(s,e).and_return(true)
@user.absence_at(s,e).should be_false
end
# example two
it "should be true when user has no interaction and he no waiting at platform" do
@user.stub!(:have_connection_or_review?).with(s,e).and_return(false)
@user.stub!(:login_absence_at?).with(s,e).and_return(true)
@user.absence_at(s,e).should be_true
end
# example three
it "should be false when user has no interaction and he waiting at platform" do
@user.stub!(:have_connection_or_review?).with(s,e).and_return(false)
@user.stub!(:login_absence_at?).with(s,e).and_return(false)
@user.absence_at(s,e).should be_false
end
end
面测试代码典型代码实现细节带测试代码完全本末倒置测试代码运行候结都确用stub假定所都have_connection_or_review?发变化返boolean值发呢测试代码依确怕吧都没起测试代码作用
另外我仅要修改have_connection_or_review?测试代码且要修改absence_at测试代码增代码维护量
相比言用stub测试代码用修改Factory数据没发变化测试代码结错误have_connection_or_review?没通测试导致absence_at运行
其实stub主要mock些本或者本应用象比tech_finish?调用file_service获Record象所文件本测试代码运行程servicestub起作用:
class A < ActiveRecord::Base
has_many :records
def tech_finish?
self.records.each do |v_a|
return true if v_a.files.size == 5
end
return false
end
end
class Record < ActiveRecord::Base
belongs_to :a
has_files # here is a service in gem
end
所应测试代码:
describe "tech_finish?" do
it "should return true when A’s records have five files" do
record = Factory(:record)
app = Factory(:a,:records=>[record])
record.stub!(:files).and_return([1,2,3,4,5])
app.tech_finish?.should == true
end
it "should return false when A’s records have less five files" do
record = Factory(:record)
app = Factory(:a,:records=>[record])
record.stub!(:files).and_return([1,2,3,5])
app.tech_finish?.should == false
end
end
Factory使用工厂便构造同模拟数据运行测试代码面例要测试absence_at涉及model:
•HistoryRecord:User课记录
•Calendar:User课程表
•Logging:User志信息
用factory-girl构造测试数据我fixture构造些测试数据fixture构造数据指定测试用例使用用Factory专门指定组测试数据
Factory.define :user_absence_example,:class => User do |user|
user.login "test"
class << user
def default_history_records
[Factory.build(:history_record,:started_at=>Time.now),
Factory.build(:history_record,:started_at=>Time.now)]
end
def default_calendars
[Factory.build(:calendar),
Factory.build(:calendar)]
end
def default_loggings
[Factory.build(:logging,:started_at=>1.days.ago),
Factory.build(:logging,:started_at=>1.days.ago)]
end
end
user.history_records {default_history_records}
user.calendars {default_calendars}
user.loggings {default_loggings}
end
测试数据构造工厂放factories.rb文件便其测试用例使用直接放测试文件before仅供本测试文件使用通factory构造仅测试用例共享同组测试数据且测试代码简洁明
before :each do
$ sudo gem install rspec v = 1.3.0
$ sudo gem install rspec-rails v = 1.3.2
安装完进入rails应用所目录运行脚本spec测试框架:
$ script/generate rspec
exists lib/tasks
identical lib/tasks/rspec.rake
identical script/autospec
identical script/spec
exists spec
identical spec/rcov.opts
identical spec/spec.opts
identical spec/spec_helper.rb
第二步 安装factory-girl命令行执行命令:
相关厂商内容
百度研究院高级科家谈规模机器习技术 猫前端发专家鬼道解读Native Web 融合 《深入浅Node.js》作者朴灵主持QCon全栈发专题 知乎联合创始兼 CTO品QCon知名移案例专题 伤筋骨百-型组织转型实例剖析 相关赞助商
全球软件发4月23-25北京敬请期待
$ sudo gem install factory-girl
config/environment/test.rb加入factory-girlgem:
config.gem "factory_girl"
spec/目录增加factories.rb文件用于所预先定义model工厂
第三步 安装autotest命令行执行命令:
$ sudo gem install ZenTest
$ sudo gem install autotest-rails
设置与RSpec集rails应用目录运行命令显示测试用例运行结
RSPEC=true autotest or autospec
自home目录增加.autotest设置所Rails应用autotest插件文件加每应用根目录文件覆盖home目录文件设置autotest插件笔者用plugin:
$ sudo gem install autotest-growl
$ sudo gem install autotest-fsevent
$ sudo gem install redgreen
设置.autotest文件.autotest加入代码
require 'autotest/growl'
require 'autotest/fsevent'
require 'redgreen/autotest'
Autotest.add_hook :initialize do |autotest|
%w{.git .svn .hg .DS_Store ._* vendor tmp log doc}.each do |exception|
autotest.add_exception(exception)
end
end
测试经验安装必要程序库写测试代码本例所应用都Rails 2.3.4发RSpec采用1.3.0版本说明问题我假定需求:判断用户间段内否迟写测试代码都遵循原则关输入输具体实现并测试代码考虑范围内行驱发根据需求我设计absence_at(start_time,end_time)两输入值start_timeend_time及输值类型boolean应测试代码:
describe "User absence or not during [start_time,end_time]" do
before :each do
@user = Factory(:user)
end
it "should return false when user not absence " do
start_time = Time.utc(2010,11,9,12,0,0,0)
end_time = Time.utc(2010,11,9,12,30,0)
@user.absence_at(start_time,end_time).should be_false
end
it "should return true when user absence " do
start_time = Time.utc(2010,11,9,13,0,0,0)
end_time = Time.utc(2010,11,9,13,30,0)
@user.absence_at(start_time,end_time).should be_ture
end
end
测试代码已经完至于absence_at我并关实现要结能让测试代码运行结确测试代码基础胆完代码并根据测试代码结断修改代码直所测试用例通
Stub使用写测试代码首先model始model能与输入输原则吻合容易手初候发现mockstub用任何象都mock并且基础stub些省构造数据麻烦度让笔者觉测试代码美丽步步深入才发现自陷入stub误区引用面例我代码实现:
class User < ActiveRecord::Base
def absence_at(start_time,end_time)
return false if have_connection_or_review?(start_time,end_time)
return (login_absence_at?(start_time,end_time) ? true : false)
end
end
按照初写测试代码思路本存三种情况即需要三用例且调用其两需要进行stub于面测试代码记完兴奋想:写测试代码真趣
before(:each) do
@user = User.new
end
describe "method " do
s = Time.now
e = s + 30.minutes
# example one
it "should be false when user have interaction or review" do
@user.stub!(:have_connection_or_review?).with(s,e).and_return(true)
@user.absence_at(s,e).should be_false
end
# example two
it "should be true when user has no interaction and he no waiting at platform" do
@user.stub!(:have_connection_or_review?).with(s,e).and_return(false)
@user.stub!(:login_absence_at?).with(s,e).and_return(true)
@user.absence_at(s,e).should be_true
end
# example three
it "should be false when user has no interaction and he waiting at platform" do
@user.stub!(:have_connection_or_review?).with(s,e).and_return(false)
@user.stub!(:login_absence_at?).with(s,e).and_return(false)
@user.absence_at(s,e).should be_false
end
end
面测试代码典型代码实现细节带测试代码完全本末倒置测试代码运行候结都确用stub假定所都have_connection_or_review?发变化返boolean值发呢测试代码依确怕吧都没起测试代码作用
另外我仅要修改have_connection_or_review?测试代码且要修改absence_at测试代码增代码维护量
相比言用stub测试代码用修改Factory数据没发变化测试代码结错误have_connection_or_review?没通测试导致absence_at运行
其实stub主要mock些本或者本应用象比tech_finish?调用file_service获Record象所文件本测试代码运行程servicestub起作用:
class A < ActiveRecord::Base
has_many :records
def tech_finish?
self.records.each do |v_a|
return true if v_a.files.size == 5
end
return false
end
end
class Record < ActiveRecord::Base
belongs_to :a
has_files # here is a service in gem
end
所应测试代码:
describe "tech_finish?" do
it "should return true when A’s records have five files" do
record = Factory(:record)
app = Factory(:a,:records=>[record])
record.stub!(:files).and_return([1,2,3,4,5])
app.tech_finish?.should == true
end
it "should return false when A’s records have less five files" do
record = Factory(:record)
app = Factory(:a,:records=>[record])
record.stub!(:files).and_return([1,2,3,5])
app.tech_finish?.should == false
end
end
Factory使用工厂便构造同模拟数据运行测试代码面例要测试absence_at涉及model:
•HistoryRecord:User课记录
•Calendar:User课程表
•Logging:User志信息
用factory-girl构造测试数据我fixture构造些测试数据fixture构造数据指定测试用例使用用Factory专门指定组测试数据
Factory.define :user_absence_example,:class => User do |user|
user.login "test"
class << user
def default_history_records
[Factory.build(:history_record,:started_at=>Time.now),
Factory.build(:history_record,:started_at=>Time.now)]
end
def default_calendars
[Factory.build(:calendar),
Factory.build(:calendar)]
end
def default_loggings
[Factory.build(:logging,:started_at=>1.days.ago),
Factory.build(:logging,:started_at=>1.days.ago)]
end
end
user.history_records {default_history_records}
user.calendars {default_calendars}
user.loggings {default_loggings}
end
测试数据构造工厂放factories.rb文件便其测试用例使用直接放测试文件before仅供本测试文件使用通factory构造仅测试用例共享同组测试数据且测试代码简洁明
before :each do
全部回答
- 1楼网友:孤老序
- 2021-04-05 03:08
定从测试代码做起,并随着不断地学习和应用,慢慢体会到测试代码的好处。
改变思路:能做到从需求到代码的过程转换,逐步细化;
简化代码:力图让每个方法都很小,只专注一件事;
优化代码:当测试代码写不出来,或者需要写很长的时候,说明代码是有问题的,是可以被分解的,需要进一步优化;
便于扩展:当扩展新业务或修改旧业务时,如果测试代码没有成功,则说明扩展和修改不成功;
时半功倍:貌似写测试代码很费时,实际在测试、部署和后续扩展中,测试代码将节省更多的时间。
改变思路:能做到从需求到代码的过程转换,逐步细化;
简化代码:力图让每个方法都很小,只专注一件事;
优化代码:当测试代码写不出来,或者需要写很长的时候,说明代码是有问题的,是可以被分解的,需要进一步优化;
便于扩展:当扩展新业务或修改旧业务时,如果测试代码没有成功,则说明扩展和修改不成功;
时半功倍:貌似写测试代码很费时,实际在测试、部署和后续扩展中,测试代码将节省更多的时间。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯