一樣是上課心得整理,不過這次的是付費課程:
另外,為了讓自己真的更加了解 RSpec 的內容,除了純練習外,也會嘗試將測試加入之前在五倍紅寶石學習所製作的專案中:
本系列心得文所用到的檔案,將會是兩者結合的結果。
什麼是 RSpec?
RSpec 是 Ruby 的測試庫,於 2005 年釋出,也是目前最多人使用的 Ruby 測試。由於是 open source,因此也開放給大眾編輯優化:
RSpec 是一種領域特定語言(domain-specific language,DSL),用來解決某一專一的特定問題,RSpec 解決的就是程式的自動化測試問題。
什麼是測試?
測試就是寫一段程式,去檢測並保證另外一段程式可以正常運作。自動化測試可以省下許多人工測試的時間,並避免由於人為原因的錯誤疏漏。同時,當我們因為需求更動程式碼時,只要啟動自動測試,就能確保其他(工程師認為)沒有影響的地方的功能也是正常的。
測試也可以視為程式碼的說明書,只要打開測試程式,就可以清楚的了解該段程式碼呼叫了什麼函式、如何運作,以及預期達到何種功效。
因此,撰寫測試碼,並根據需求一起更新維護(否則測試出來的結果會不符合預期),對一個日趨龐大的專案來說,是百利無一害的。
單元測試(Unit Test)與點到點測試(End to End test)
測試可以分成幾個類型:
・單元測試(Unit Test):在測試的金字塔示意圖中,可以看到單元測試在金字塔的最底端,也佔了最大的部分。單元測試通常只聚焦在單一功能上,測試對象是一個類別、一個模組甚至是一個方法,目的是保證專案的每個碎片都能正常運作。
・整合測試 (Integration Test):將單獨的功能組合起來成為一個複合的模組,並測試彼此之間是否能正常溝通、運作。
・點到點測試(End to End test):又稱為驗收測試(acceptance),是將整個功能流程從頭測試到尾,以電商網站來說,可能是使用者登入、瀏覽網頁、將商品加入購物車並付款購買成功的整個流程,這代表每個負責的部位都必須正確運作。
由於點到點測試所包含的範圍廣大,測試碼的撰寫相較於單元測試要困難上許多,測試的速度較慢,同時任何程式碼的變動也都可能影響測試結果。
測試驅動開發(Test-Driven Development,TDD)
測試驅動開發顧名思義,就是先構築測試碼再開始開發功能。這可能會讓人感到困惑:如果我沒有程式碼,要如何去測試它?
但這正是 TDD 的目的:它讓工程師在真的開始撰寫功能之前先思考功能的內容與運作模式,需要多少類別?函式(或類別)之間要如何彼此溝通?公開與私有的方法要如何編制?每個類別的內容是否合理?還是需要再分拆?等等的問題,這樣的思考會幫助我們一步一步建構完善的程式碼。
通常工程師在收到需求時,都會急著(可能也是需求方給的開發時程過短)將功能實作出來,此時就會無法顧及到程式的完善性,可能是沒有想清楚方法的切割或類別之間的溝通,函式的開放或封閉設定等等,長期下來就會導致專案的程式碼一團混亂,TDD 開發模式可以讓我們盡量避免這種結果。
TDD 的概念有點像紅綠燈,可以分成三種燈號:紅燈代表測試失敗(在還沒開始正式構築程式碼前都會是這個狀態),綠燈代表測試成功(代表你已經寫出了至少足以通過測試的程式碼),黃燈代表重構,也就是將程式碼整理得更簡潔、易懂;TDD 使用這三種燈號的循環來維護程式碼。
RSpec 生態系統
RSpec 由三個 Ruby Gem 組成:
・RSpec-core:測試函式庫,並負責執行測試
・RSpec-expectations:提供檢查結果的方法
・RSpec-mocks:生成用於測試的偽類別與偽物件(通常用於單元測試)
安裝 RSpec 與初始化
如果只是單純要在 Rails 環境中練習 RSpec,只要在終端機鍵入以下指令:
gem install rspec
系統便會自行安裝 rspec。
接著先來嘗試啟動 RSpec,首先先創一個資料夾,比方我們這裡叫做 spec:
mkdir spec
然後進入資料夾,鍵入以下指令初始化 rspec:
rspec --init
這會產生以下結果:
create .rspec
create spec/spec_helper.rb
這個時候只要使用程式編輯軟體(我是用 VS code)就能打開剛剛所創立的資料夾,在名為 .rspec 的檔案中,可以看見一行設定:
--require spec_helper
這行設定會幫我們載入 rspec 的預設 helper,因此可以直接在其他的測試檔案中使用,不需再特別載入。
接下來來看看 spec/spec_helper.rb 這個檔案,這裡面是 helper 的設定檔,可以依據需要自己調整設定。在檔案的 20 到 38 行可以看到以下文字:
上面是測試期望條件的設定,如果希望使用 ruby 內建的 minitest 方法,可以在此更改(我沒用過就是了),當然預設是使用 rspec 的標準方法。
下面是 mock 的設定,讀註解的解釋是說可以預防使用為定義的模組或方法,應該是某種防呆機制。
再往下轉會發現一大堆註解掉的設定,一樣可以根據需要決定要不要拿掉註解,具體的使用方法都寫在註解裡。
如果是要將 RSpec 套用到專案上,那就必須安裝 rspec-rails 這個套件,執行 bundle install 成功後,再輸入以下指令初始化:
rails g rspec:install
全部都設定完成之後,就可以開始練習 RSpec 了。
參考資料: