[Testing] 寫單元測試的正確姿勢(一)

[Testing] 寫單元測試的正確姿勢(一)

更新於 發佈於 閱讀時間約 6 分鐘

在寫程式的過程中,最讓人頭痛的就是當功能越來越複雜,修改某一塊程式碼時,突然發現別的地方出問題了。怎麼樣才能又快又好地確保程式碼沒毛病?這時候,測試就成了我們的好幫手。

很多人以為測試只是驗證程式碼的功能對不對,但其實它的作用比這更大。測試不僅可以幫我們找到問題,還可以讓程式碼變得更清晰、更好維護,甚至在未來功能變更時幫我們省下不少麻煩。

測試的價值?

  1. 確認程式碼行為:確保它做的就是我們想要的。
  2. 提早發現問題:快速定位那些可能潛伏的 bug。
  3. 讓人放心改程式碼:有了測試,重構或新增功能時不用再提心吊膽。
  4. 省時又省力:自動化測試讓我們不用再重複做繁瑣的手動測試。
  5. 設計更好的程式碼:讓結構更清楚,也更容易被接手或修改。

每種類型的測試都有不同的測試目的和覆蓋範圍,可以從不同的角度來確保軟體的品質,而PHPUnit 支持多種不同的測試類型,包括單元測試、功能測試和功能測試…等。這裡主要會講到的兩大項為Unit TestFeature Test

Unit Test(單元測試)

  • 測試範圍
    • 單一類別、方法或模組的行為。
    • 不依賴於外部系統或框架功能(如路由、中介層)。
  • Mock 的使用
    • 將所有外部依賴(例如 Repository、Service)進行 Mock。
    • 測試的重點是目標類別內的邏輯,而不是依賴的具體實現。
  • 適用場景
    • Service \ Repository
    • 驗證方法是否正確調用依賴、處理資料和回傳結果。

Feature Test(功能測試)

  • 測試範圍
    • 應用程式的完整功能流。
    • 通常測試控制器行為,包括請求、回應和中介層的協作。
  • Mock 的使用
    • 在需要模擬外部系統(如 API 請求)時使用 Mock,但大多依賴真實的資料和系統行為。
  • 適用場景
    • 測試整個測驗功能,例如:
      1. 發送請求到 Controller\ Validation
      2. 通過 Mock Service 處理邏輯。
      3. 驗證回應是否正確。

Service 屬於 Unit Test 的原因

  • 單一類別測試
    • 測試的是 Service 的方法是否能按照業務需求正確執行。
  • Mock 依賴
    • 測試中使用 Mock 的 Repository 和其他 Service,重點關注 Service 本身的邏輯。
  • 與外部系統分離
    • 測試不涉及Controller、Route或Request流程。

如何結合 Feature 和 Unit 測試

  1. Unit Test
    • Service 進行細粒度測試。
    • 模擬所有外部依賴,驗證邏輯的正確性。
  2. Feature Test
    • 測試 Controller 是否正確調用 Service
    • 驗證整個功能流,包括請求和回應。

這樣可以確保程式的不同層級都被充分測試,既有精細的單元測試,也有高層的整合測試。


單元測試的 3A 原則

  1. Arrange(準備): 設定測試所需的前置條件,包括初始化資料、模擬外部依賴等。
  2. Act(執行): 呼叫需要測試的方法或功能。
  3. Assert(驗證): 驗證執行結果是否符合預期。

如何執行測試?

使用 vendor/bin/phpunit 執行測試:

當你執行 vendor/bin/phpunit,你實際上是在執行專案本地的 PHPUnit,這個版本是根據 composer.json 安裝的特定版本。

因為可能同時開發不同版本的專案,每個專案裡面的phpunit版本不一定一樣,所以進入docker容器,在下指令會比較不會出錯。

範例:

--filter {functionName} -> 只執行某一個測試

vendor/bin/phpunit Tests/Feature/Controllers/ExamControllerTest.php --filter testRegisterUsersSuccess
  • 指定測試檔案Tests/Unit/Services/ExamServiceTest.php
  • 指定測試方法--filter testSyncMercerAssessmentUpdatesDatabase


備註:

  • 在 Windows 系統中,路徑分隔符是反斜線 (\),但由於反斜線在 CLI 中具有特殊含義(例如轉義),需要加倍反斜線來正確解析路徑。
  • 如果使用 Linux 或 macOS,可以直接使用單斜線 /

小結

測試不僅能幫助我們檢查程式是否正確運作,還能促進程式碼的結構化與可維護性。在應用程式開發中,結合 Unit Test 和 Feature Test 可以確保程式邏輯細節與整體功能流都能無誤運行。

下一篇文章將進一步深入實際測試的應用範例,尤其是如何使用 Laravel 的 Factory 來建立測試資料,並搭配具體測試案例來演示 PHPUnit 測試的執行過程。我們將從測試資料的建立到完整測試的執行步驟,帶領大家實際操作,體驗單元測試與功能測試如何在開發流程中發揮威力。

avatar-img
欸! 是彼得的資料庫
62會員
44內容數
歡迎來到彼得的沙龍,在這裡,我將與你分享書籍精華的智慧、人際溝通的技巧、理財增值的秘訣,以及情緒管理的策略。不僅幫助你打好財務基礎,還能引領你在人生的每個環節中游刃有餘。如果你渴望成長,並追求更充實的生活,這裡就是你值得關注的空間。立即加入,與我一起探索成長的無限可能!
留言
avatar-img
留言分享你的想法!
本文介紹了 Docker 的基本概念,包括 Docker Image、Docker Container、Dockerfile、Docker Compose 及其應用情境,如開發與測試環境、微服務架構和持續整合/持續部署。瞭解這些內容能幫助開發人員更有效地利用 Docker 進行應用程式的部署和管理。
本文探討如何利用政府提供的YouBike開放數據進行數據分析,以揭示共享單車系統的使用趨勢。作者使用Google Apps Script分析不同時間點的YouBike使用率,並通過線性回歸預測供需平衡,以及針對特定站點的使用模式進行深入挖掘。最後總結了公館不同出口的使用情況,提供了最佳的租借選擇。
在進行SQL查詢邏輯更改時,需要適當地使用SubQuery和join來達到新的排序需求。本文將介紹原本的撈取邏輯、需求以及如何使用SubQuery來解決新的排序需求。
本文介紹了 Docker 的基本概念,包括 Docker Image、Docker Container、Dockerfile、Docker Compose 及其應用情境,如開發與測試環境、微服務架構和持續整合/持續部署。瞭解這些內容能幫助開發人員更有效地利用 Docker 進行應用程式的部署和管理。
本文探討如何利用政府提供的YouBike開放數據進行數據分析,以揭示共享單車系統的使用趨勢。作者使用Google Apps Script分析不同時間點的YouBike使用率,並通過線性回歸預測供需平衡,以及針對特定站點的使用模式進行深入挖掘。最後總結了公館不同出口的使用情況,提供了最佳的租借選擇。
在進行SQL查詢邏輯更改時,需要適當地使用SubQuery和join來達到新的排序需求。本文將介紹原本的撈取邏輯、需求以及如何使用SubQuery來解決新的排序需求。