如果想測試各個控制器、頁面之間的流程互動,可以繼承ActionDispatcher::IntegrationTest,它繼承自ActiveSupport::TestCase,新增了一些方法,可測試跨動作或控制器的流程,由於流程實際是在測試應用程式的行為,因此屬於整合測試的範疇。
可以使用rails產生整合測試的骨架,例如:
~gossip\$ gossip\$ rails generate integration_test user_flows
invoke test_unit
create test/integration/user_flows_test.rb
invoke test_unit
create test/integration/user_flows_test.rb
接著編輯test/integration/user_flows_test.rb,以下是個針對 Cookie 中範例,使用者從首頁被轉發至登入頁而後登入成功的測試:
- user_flows_test.rb
require 'test_helper'
class UserFlowsTest < ActionDispatch::IntegrationTest
fixtures :all
test "forward user to login successfully" do
get "/tests/index"
assert_redirected_to :controller => "tests", :action => "login"
follow_redirect!
assert_equal "/tests/login", path
post "/tests/login", {user: "caterpillar", passwd: "123456"}
assert_response :success
assert_equal "caterpillar", assigns(:user)
assert_select "title", "Welcome"
end
end
如果要測試多個使用者以上的行為,測試的程式碼會變得冗長且重複,此時可以嘗試利用Ruby的特性自訂DSL,讓測試程式的語意更為清晰。例如:
- user_flows_test.rb
require 'test_helper'
class UserFlowsTest < ActionDispatch::IntegrationTest
fixtures :all
test "forward user to login" do
visitor1 = forward(:visitor1)
visitor1.login("caterpillar", "123456")
visitor1.assert_select "title", "Welcome"
visitor2 = forward(:visitor2)
visitor2.login("someone", "123456")
visitor2.assert_select "title", "Login"
end
module UserDsl
def login(user, passwd)
post "/tests/login", {user: user, passwd: passwd}
if redirect?
follow_redirect!
end
end
end
def forward(user)
open_session user do |sess|
sess.extend(UserDsl)
sess.get "/tests/index"
sess.assert_redirected_to :controller => "tests", :action => "login"
sess.follow_redirect!
sess.assert_equal "/tests/login", sess.path
end
end
end
其它整合測試的例子,可以參考 ActionDispatcher::IntegrationTest 文件,或者是 A Guide to Testing Rails Applications 中的 IntegrationTest。