作為一個RoRer,作為一個自動化測試狂人,作為一個完美主義者。我無法忍受在測試Rails應用時,居然要打開3個窗口:一個Vim窗口,一個Spork窗口,一個Autotest窗口。更加無法忍受的是有時需要手工執(zhí)行autotest (因為之前Autotest的配置原因,對于view文件或者一些非ruby文件無法自動檢測)。
關(guān)于Rails自動化測試的基本配置,請參考我之前寫的兩篇文章《Rails3的自動化測試概述與配置》 和 《針對Spork無法自動Reload配置文件的解決方法》。這個方案的原理就是:
啟動Guard
|--> 啟動Spok,執(zhí)行pre_fork方法,加載測試環(huán)境
啟動Autotest
|--> 自動執(zhí)行rspec spec/,并以后臺進程的方式存在,不退出
新的方案中,我取消了Autotest這個組件,改用了guard-rspec,它也可以自動地檢測文件的改變并執(zhí)行rspec spec命令,同時保留了guard-spork,用于縮短測試時間,提高測試效率。
我們要修改的文件會涉及到4個:
A. Gemfile
B. .rspec
C. Guardfile
D. rspec_helper.rb
先看第一步:更新Gemfile

這一步有3個需要特別注意的地方:
A. gem 'rspec':這一步一定要使用最新版本的Rspec(2.4以上),否則無法配合libnotify顯示測試結(jié)果
B. gem 'rb-inotify'、gem 'libnotify':這兩個是必須的。原來是在.atuotest文件中指定
C. bundle update:修改完Gemfile后記得要執(zhí)行這一半更新bundle
第二步:更新rspec

這里告訴Rspec,我們要采用帶顏色的輸出。注意這里不需要加參數(shù)--drb,否則在運行期間會出現(xiàn)端口已被綁定的警告
第三步:更新GuardFile
GuardFile的生成,可以使用guard init <guard-name>,例如:guard init spork , guard init rspec。這一步相當重要,Spork和Rspec能否成功自動運行,就是靠Guard-spork和Guard-spec的配置了。
首先我們來看Guard-spork的配置

這里我們讓Guard監(jiān)控Spork的指定文件,一旦這些文件發(fā)生改變了,自動加載。可以看到這些文件基本都是屬于系統(tǒng)的配置文件。
下面是Guard-rspec的配置,這是最關(guān)鍵的一步,讓Guard監(jiān)控指定的測試文件,除了自動加載外,我們還可以指定要運行哪些測試:

我們看到和Guard-spork的配置相比,這里多了一個{...}的指令。這就是用來指定當相應的文件發(fā)送改變時,需要執(zhí)行哪些測試。如果沒有指定則默認運行匹配的測試文件。另外一個需要注意的地方是::cli => "--color --format nested -- fail-fast --drb",這句話的作用是:用帶顏色的輸出區(qū)分成功和失敗case,同時格式化輸出(非常有用,輸出結(jié)果簡潔明了),同時優(yōu)先運行失敗的測試。
最后一步是配置: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,令到測試失敗。這時會出現(xiàn):

由于前面我們加了一些格式化的參數(shù)。所以我可以看到Rspec的輸出都很簡潔明了(綠色是通過的,紅色是失敗的。而且每個測試結(jié)果都按照依賴類型,嵌套關(guān)系進行組織)

現(xiàn)在我們修改rb文件,讓測試通過。我們會發(fā)現(xiàn)這次Rspec只運行了layout_links_spec.rb這個測試,而不會執(zhí)行其他已經(jīng)通過的測試。

我們在GuardFile中指定了對view文件的監(jiān)測,所以現(xiàn)在不單單是ruby文件,即便是普通的erb,haml文件的改變都會令Rspec自動測試了。下面的例子我故意把link_to前面的"="號去掉,這個時候Guard-rspec會發(fā)現(xiàn)文件的改變,并自動reload和運行對應的集成測試。

測試的結(jié)果如下圖所示(可以看到Rspec只運行了我們在GuardFile中指定的測試,而不會運行其他不相關(guān)的測試)

再次修改view文件,確保測試通過

現(xiàn)在終于可以享受我們高效的Rails自動化測試環(huán)境了!Enjoy Guard, Enjoy automated testing! -------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
posted on 2011-08-31 00:44
Paul Lin 閱讀(1847)
評論(1) 編輯 收藏