在敏捷開發的實踐中,測試驅動是少不了的。這篇來看看在rails中的一個測試驅動開發的例子。
在前面我們編寫並進行了一些單元測試和功能測試,現在,我們的客戶突然要求添加一個功能:系統的每個使用者都可以對商品進行查詢。
我們先初步的畫了一些草圖,來整理我們的思路和設計,然後開始寫代碼。對於具體的實現,我們已經有了大致的思路,但是如果有更多的反饋資訊的話會有助於我們走在正確的道路上。我們會在深入到代碼之前,編寫測試代碼。考慮我們的代碼將怎樣工作,確定一些規約,當測試通過,你的代碼就OK了。
現在,我們來考慮一下查詢功能的測試,應該由哪個controller來控制查詢操作呢?使用者和管理員都可以進行查詢操作,我們可以在store_controller.rb或者admin_controller.rb中添加一個search()的Action,但是這裡我們添加一個SearchController,並且含有一個方法search。在rails命令列執行命令:
depot>ruby script/generate controller Search search
我們看到,在app/controllers和test/functional目錄下已經產生了對應的檔案。但是現在我們並不關心SearchController的search方法的實現,我們關心的是在測試時我們所期望看到的結果。現在添加測試代碼,在test/functional/search_controller_test.rb中添加test_search方法:
我們首先想到的是調用search的Action,然後判斷是否得到了響應:
get :search, :title => "Pragmatic Version Control"assert_response :success
根據之前的草圖,我們應該在頁面上顯示一個flash資訊,所以我們要判斷flash資訊的文本,以及是否顯示了正確的頁面:
assert_equal "Found 1 product(s).", flash[:notice]assert_template "search/results"
然後我們想要判斷查詢所得到的商品資訊:
products = assigns(:products)assert_not_nil productsassert_equal 1, products.sizeassert_equal "Pragmatic Version Control", products[0].title
我們還想判斷用來顯示查詢結果的頁面的一些內容,我們查詢到的商品會作為列表在頁面上顯示,我們使用catelog視圖相同的css樣式:
assert_tag :tag => "div", :attributes => { :class => "results" }, :children => { :count => 1, :only => { :tag => "div", :attributes => { :class => "catalogentry" }}}