作为一个RoRer,作为一个自动化测试狂人,作为一个完美主义者。我无法忍受在测试Rails应用时,居然要打开3个窗口:一个Vim窗口,一个Spork窗口,一个Autotest窗口。更加无法忍受的是有时需要手工执行autotest (因为之前Autotest的配置原因,对于view文件或者一些非ruby文件无法自动检测)。
关于Rails自动化测试的基本配置,请参考我之前写的两篇文章《Rails3的自动化测试概述与配置》 和 《针对Spork无法自动Reload配置文件的解决方法》。这个方案的原理就是:
启动Guard
|--> 启动Spok,执行pre_fork方法,加载测试环境
启动Autotest
|--> 自动执行rspec spec/,并以后台进程的方式存在,不退出
新的方案中,我取消了Autotest这个组件,改用了guard-rspec,它也可以自动地检测文件的改变并执行rspec spec命令,同时保留了guard-spork,用于缩短测试时间,提高测试效率。
我们要修改的文件会涉及到4个:
A. Gemfile
B. .rspec
C. Guardfile
D. rspec_helper.rb
先看第一步:更新Gemfile
这一步有3个需要特别注意的地方:
A. gem 'rspec':这一步一定要使用最新版本的Rspec(2.4以上),否则无法配合libnotify显示测试结果
B. gem 'rb-inotify'、gem 'libnotify':这两个是必须的。原来是在.atuotest文件中指定
C. bundle update:修改完Gemfile后记得要执行这一半更新bundle
第二步:更新rspec
这里告诉Rspec,我们要采用带颜色的输出。注意这里不需要加参数--drb,否则在运行期间会出现端口已被绑定的警告
第三步:更新GuardFile
GuardFile的生成,可以使用guard init <guard-name>,例如:guard init spork , guard init rspec。这一步相当重要,Spork和Rspec能否成功自动运行,就是靠Guard-spork和Guard-spec的配置了。
首先我们来看Guard-spork的配置
这里我们让Guard监控Spork的指定文件,一旦这些文件发生改变了,自动加载。可以看到这些文件基本都是属于系统的配置文件。
下面是Guard-rspec的配置,这是最关键的一步,让Guard监控指定的测试文件,除了自动加载外,我们还可以指定要运行哪些测试:
我们看到和Guard-spork的配置相比,这里多了一个{...}的指令。这就是用来指定当相应的文件发送改变时,需要执行哪些测试。如果没有指定则默认运行匹配的测试文件。另外一个需要注意的地方是::cli => "--color --format nested -- fail-fast --drb",这句话的作用是:用带颜色的输出区分成功和失败case,同时格式化输出(非常有用,输出结果简洁明了),同时优先运行失败的测试。
最后一步是配置:rspec_helper.rb文件
require 'spork'
Spork.prefork do
# Loading more in this block will cause your tests to run faster. However,
# if you change any configuration or code from libraries loaded here, you'll
# need to restart spork for it take effect.
# --- Instructions ---
# - Sort through your spec_helper file. Place as much environment loading
# code that you don't normally modify during development in the
# Spork.prefork block.
# - Place the rest under Spork.each_run block
# - Any code that is left outside of the blocks will be ran during preforking
# and during each_run!
# - These instructions should self-destruct in 10 seconds. If they don't,
# feel free to delete them.
#
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# == Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.mock_with :rspec
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end
OK~,大功告成。下面开始我们的测试。首先在Console下启动Guard。如图所示:首先Guard会启动Spork,然后找到Rspec。神奇的是这时候Guard居然会自己运行Rspec了。我们再也无需要重新开多一个窗口就可以在同一个终端下即运行Spork,又运行Rspec,还可以自动reload。多爽!!!
我们尝试修改一下rb文件:/requests/layout_links_spec.rb,令到测试失败。这时会出现:
由于前面我们加了一些格式化的参数。所以我可以看到Rspec的输出都很简洁明了(绿色是通过的,红色是失败的。而且每个测试结果都按照依赖类型,嵌套关系进行组织)
现在我们修改rb文件,让测试通过。我们会发现这次Rspec只运行了layout_links_spec.rb这个测试,而不会执行其他已经通过的测试。
我们在GuardFile中指定了对view文件的监测,所以现在不单单是ruby文件,即便是普通的erb,haml文件的改变都会令Rspec自动测试了。下面的例子我故意把link_to前面的"="号去掉,这个时候Guard-rspec会发现文件的改变,并自动reload和运行对应的集成测试。
测试的结果如下图所示(可以看到Rspec只运行了我们在GuardFile中指定的测试,而不会运行其他不相关的测试)
再次修改view文件,确保测试通过
现在终于可以享受我们高效的Rails自动化测试环境了!Enjoy Guard, Enjoy automated testing! -------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要尽力打好一手烂牌。
posted on 2011-08-31 00:44
Paul Lin 阅读(1835)
评论(1) 编辑 收藏