延續前文,針對結帳、下單流程撰寫功能測試。
def test_checkout
test_add_to_cart # 復用前一測試,確保 session[:cart] 有商品
get :checkout
assert_response :success
assert_not_nil assigns(:order)
assert_template "store/checkout"
end
直接呼叫其他測試方法建立前置條件,避免重複程式碼。
def test_save_invalid_order
test_add_to_cart
post :save_order, :order => { :name => 'fred', :email => nil }
assert_response :success
assert_template "store/checkout"
# 驗證錯誤訊息顯示區塊
assert_tag :tag => "div", :attributes => { :class => "fieldWithErrors" }
# 購物車商品應保留
assert_equal 1, session[:cart].items.size
end
def test_save_valid_order
test_add_to_cart
assert_equal 1, session[:cart].items.size
assert_equal 1, Order.count # fixtures 已載入 1 筆
post :save_order, :order => @valid_order_for_fred.attributes
assert_redirected_to :action => 'index'
assert_equal "Thank you for your order.", flash[:notice]
follow_redirect # 模擬瀏覽器跟隨導向
assert_template "store/index"
assert_equal 0, session[:cart].items.size # 購物車已清空
assert_equal 2, Order.find(:all).size # 新增 1 筆訂單
end
test/fixtures/orders.yml:
valid_order_for_fred:
id: 1
name: Fred
email: fred@flintstones.com
address: 123 Rockpile Circle
pay_type: check
測試中使用 @valid_order_for_fred = Order.find(1) 取得 fixture 物件(Rails 自動建立實例變數)。
錯誤:<"Thank you for your order."> expected but was <"Thank you for your order">
修正控制器 flash[:notice] = "Thank you for your order." 確保句號一致。
執行測試後檢查資料庫發現重複訂單,因 fixtures 載入 + 測試新增。解決:
self.use_transactional_fixtures = true 交易回滾teardown 手動清理 Order.delete_alllog/test.log 記錄測試過程所有 SQL,可驗證查詢次數、參數綁定、交易邊界。
assert_tag :content => /can't be blank/)