[Rails.Test.Prescriptions]系列之一:0基础的Test Rails...
2019獨角獸企業重金招聘Python工程師標準>>>
Before Start
###個人簡介### 大學本科,大四,軟件工程專業,新手。 ###目的### 記錄自己的讀書,加強記憶。 ###注意### 雖然學過測試,但基本忘干凈了,雖然接觸了一陣ruby on rails,但還是菜鳥等級,所以錯誤難免(還加入了不少個人理解),所以如果有讀者,請自己分別對錯。有錯誤歡迎前輩指出。另外因為本人也是菜鳥,所以基本上都會從Hello World開始。 ##Intro## 哪怕一個剛剛開始學習軟件的人,也知道軟件測試必不可少,但是還是有無數的新手跳過這一部分(包括我自己),在撞碎了無數南墻之后,回過頭來看測試。
####為什么需要測試####
##測試流程## 無論是TDD還是BDD,都有一個Red-Green循環。寫測試,失敗-->寫代碼-->測試,成功(因為大多數測試失敗是紅色的 成功是綠色的 所以叫Red-Green循環,不過rails都是黑的。。。)
書里內容,詳細的介紹了Red-Green循環
這里還有一個例子,參見最后那個完整的例子。
##Rails中的測試## 不截圖了,以一個新手新建五分鐘的項目來說,在項目中有個test文件夾,在test文件夾下面還有5個文件夾。
- units 單元測試,恩,在rails里叫單元測試不太準確,準確的說是測試model層的。
- functional 功能測試,ok,controller和views
- fixtures 數據,測試的數據(等到model測試的時候會介紹用factory方式來生成測試數據)。
- integrations 集成測試,簡單的說就是 functionals一般測試一個controller的一個方法,集成測試可以測試跨controller的多個方法的連鎖功能。
- performances 性能測試,這個沒有解釋的必要了吧。
##基本知識## units里面的tests一般是繼承自ActiveSupport::TestCase(<Test::Unit::TestCase) functionals里面的tests繼承自ActionController::TestCase(<ActiveSupport::TestCase)
一個測試是指
<!-- lang: ruby --> test "should be unique" do#some assertions end在test后面的參數是如果測試失敗輸出的話,在代碼塊里應該放置你的操作和你預期的結果(無數assert方法)
另外每個TestCase還有setup和teardown方法,前者用于在所有test執行之前執行(假設一個類稱為testcase 一個單獨的test方法語句稱為test),后者用于在所有test執行之后執行。 比如我在一個testcase里有test "should be a" do end 和test "should be b" do end 兩個測試,執行順序是setup test_a teardown 然后再setup test_b teardown
比如你每個test都要使用一個user對象 就可以在setup中構建這個user @user = User.create(:name=>"John")
ActiveSupport 對 原本的testcase進行了擴展,可以在一個測試內放置多個setup。
對于test的額外說明,你可以在一個test內設置多個assertion,但是這樣不好,應該盡量吧assertion分開,因為如果一個test內,第一個assertion失敗,后面的assertion都不會繼續執行。
##Let`s Go## 完整的例子了,書中對應內容Chapter 3
####目的:創建一個StatusReport####
<!-- lang: ruby --> test "creation of status report with data" doassert_difference('StatusReport.count', 1) dopost :create, :status_report => {:project_id => projects(:one).to_param,:user_id => users(:one).to_param,:yesterday => "I did stuff",:today => "I'll do stuff"}endactual = assigns(:status_report)assert_equal(projects(:one).id, actual.project.id)assert_equal(users(:one).id, actual.user.id)assert_equal(Date.today.to_s(:db), actual.status_date.to_s(:db))assert_redirected_to status_report_path(actual) end關于上面代碼的解釋
執行 rake test:functionals 毫無意外的會失敗
<!-- lang: ruby --> 1) Error:test_creation_of_status_report_with_data(StatusReportsControllerTest):ArgumentError: wrong number of arguments (1 for 0)/test/functional/status_reports_controller_test.rb:58:in `to_s'/test/functional/status_reports_controller_test.rb:58:in`test_creation_of_status_report_with_data'意思是actual.status_date.to_s(:db)這個方法不應該帶參數,但其實錯誤不是這個,而是status_date為nil了 因為nil可以to_s 所以沒有報錯 而是報參數錯誤
修改controller里的create
<!-- lang: ruby --> def create@status_report = StatusReport.new(params[:status_report])@status_report.status_date = Date.today # ==> the new line## the rest of the method as before end測試通過 ####重構#### 雖然上面的修改測試通過了,但是我們都知道,rails應該把邏輯放進model里,所以我們準備吧設置status_date的方法放進model
寫units測試
<!-- lang: ruby --> test "saving a status report saves the status date" doactual = StatusReport.newactual.saveassert_equal(Date.today.to_s, actual.status_date.to_s)end修改model
<!-- lang: ruby --> class StatusReport < ActiveRecord::Basebelongs_to :projectbelongs_to :userbefore_save :set_status_datedef set_status_dateself.status_date = Date.todayend end上面的測試雖然目前來看是通過了,但是因為before_save在每次edit的時候也會被調用,這樣就會修改我們原有的日期,這很明顯不是我們想要的,繼續重構。 寫units測試
<!-- lang: ruby --> test "saving a status report that has a date doesn't override" doactual = StatusReport.new(:status_date => 10.days.ago.to_date)actual.saveactual.reloadassert_equal(10.days.ago.to_date.to_s, actual.status_date.to_s) end修改model
<!-- lang: ruby --> def set_status_dateself.status_date = Date.today if status_date.nil? end測試通過,第一個例子告一段落。
##Summary##
該書第一部分的目的:了解Rails測試以及相關部分簡介。 總結:
- rails的model測試在units里
- rails的controller測試在functionals里
- rails默認使用fixture來生成假數據
- 在測試過程中,通過之后的重構很重要
轉載于:https://my.oschina.net/jerrytao/blog/103504
總結
以上是生活随笔為你收集整理的[Rails.Test.Prescriptions]系列之一:0基础的Test Rails...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FindFileByContent
- 下一篇: selenium search