單元測試

何謂單元測試

單元測試的定義

單元測試在早期使用 Smalltalk 程式語言進行開發時便已存在。單元測試是讓開發者提升程式品質、加深理解程式方法和類別的最佳方法之一。

一個優秀的單完測試為一段自動化的程式碼,這段程式碼會呼叫待測試的工作單元,並對這個單元的單一執行結果的假設進行驗證。單元測試往往會透過單元測試框架進行撰寫。單元測試需要很容易進行撰寫、執行快速,執行結果可靠,程式碼易讀並且容易維護。只要程式碼沒有改動,測試結果都會是一致的。

工作單元指的是從呼叫系統的一個公開方法到產生一個測試可見的最終結果的執行期間所發生的行為。測試可見的最終結果代表的是只需要透過公開的系統 API 就可以觀察到的結果,並不需要知道程式碼的內部狀態。常見形式如:

  1. 被呼叫的公開方法回傳的回傳值
  2. 呼叫方法的前後,系統可見的狀態或行為發生變化,這些變化不需要透過查詢私有狀態就可以取得和判斷
  3. 呼叫不受測試的第三方系統,該第三方系統不會有回傳值或是回傳值不會拿來使用

註,被測試的的對象又稱 System Under Test, SUT,被測試的系統

工作單元大至包含特定功能的許多類別和函數,小至一個方法。越大的工作單元可以表達 API 對於使用者的能見度越高,因此而較好維護。然而切得過小的工作單元容易產生需要偽造許多中間狀態的物件,這些物件並非公開 API 真實會產生的最終結果,這是一種 over specification

好的單元測試可以省掉日後的維護成本避免浪費時間花在小細節除錯,並且可以提高程式的品質。然而不好的單元測試卻可能讓你花掉大量的時間在撰寫測試然而卻要花更大量的時間維護它,甚至最終又回到使用手動測試。

單元測試的特性

開發人員在程式撰寫時都會進行過單元測試,不論是在程式碼中加入 print 將物件狀態、方法執行結果輸出,或是撰寫 GUI 介面時手動填入表單的內容並檢查是否如預期執行欄位檢驗,然而這些測試的方法有著幾個可能的缺點,如無自動化、不同時間點執行的結果可能會不一致、不同使用者執行的結果可能會不一致、測試不容易被實現等等。單元測試會有著以下的特性:

  1. 自動化且可以被重複執行
  2. 容易被實現
  3. 非臨時性的,不論什麼時間點都有存在的意義
  4. 任何人都可以輕易執行
  5. 執行快速
  6. 執行結果應該一致
  7. 可以完全掌控測試單元
  8. 完全隔離的,與其他測試無相依、獨立於其他測試
  9. 簡單清楚說明測試失敗的原因及預期的結果應為何

這些特性可以透過下列五個問題檢視自己的測試是否是單元測試: