A test for invalid submission
在沒有完全支持測試的強大 Web 框架出現之前,都必須透過手動來測試表單,你必須要測試無效跟有效的資訊,每次修改時又要重複幾遍這樣的動作。
Rails 可以編寫測試,自動測試表單,接下來我們要寫一個測試,測試當表單提交無效的資訊錯時,會不會正常反映出相關資訊。
現在建立一個整合測試(integration test)的檔案,用來測試註冊,名稱為 users_signup ,慣例使用 resource 的複數名稱:
$ rails generate integration_test users_signup
invoke test_unit
create test/integration/users_signup_test.rb
之後會使用這個檔案,繼續編寫有效的註冊測試。
這個測試的主要目的是,當提交無效資訊並點擊送出按鈕之後,並不會建立新使用者。(對錯誤訊息的測試留在練習題)方法是檢查使用者的數量。在測試中會使用 count 方法,這個方法在 Active Record class 中(包括 User class)都能應用:
$ rails console
> User.count
=> 0
因為之前把資料庫 reset 了,所以現在使用者為 0 個。我們要使用 assert_select 檢查相關頁面的 HTML 元素(這個方法只能測試以後不會修改的元素)。
首先我們會先用 get 方法讀取註冊頁面:
get signup_path
為了測試表單提交後的狀態,我們要向 users_path 發出 POST 請求:
assert_no_difference 'User.count' do
post users_path, user: { name: "",
email: "user@invalid",
password: "foo",
password_confirmation: "bar" }
end
這裡使用 create action 傳給 User.new 的 params[:user] hash。把 post 方法放在 assert_no_difference 方法的 block 裡面,並把 assert_no_difference 方法的參數,設定為 User.count 字串。這段程式碼被執行時,會去比較 User.count 在 assert_no_difference block 中,前後的值的狀態(before and after of the contents of the assert_no_difference block)。
這段程式碼等於會先計算使用者的數量,然後用 POST 發送資料,最後檢查使用的數量沒變:
before_count = User.count
post users_path, ...
after_count = User.count
assert_equal before_count, after_count
上述兩種方式都是同樣的作用,但使用 assert_no_defference 會更簡潔清楚,也是 Ruby 慣用的語法。
上述用到的
get和post其實在技術上比較無關緊要,實際上也不是一定要先get到註冊頁面才能post資料。原作者習慣包含這兩個步驟,看起來會更清楚,也可以再次確認註冊頁面有沒有被正確的渲染(render)。
最後,完整的測試程式碼如下:
test/integration/users_signup_test.rb
require 'test_helper'
class UsersSignupTest < ActionDispatch::IntegrationTest
test "invalid signup information" do
get signup_path
assert_no_difference 'User.count' do
post users_path, user: { name: "",
email: "user@invalid",
password: "foo",
password_confirmation: "bar" }
end
assert_template 'users/new'
end
end
assert_template 是用來檢查失敗的提交訊息有沒有重新載入正確的頁面(new action)。
因為我們在編寫測試之前,就先把應用程式碼寫好了,所以測試必然會通過(Green):
$ bundle exec rake test