軟體測試介紹 — 測試驅動開發 (TDD)

2024年10月17日

💎 加入 E+ 成長計畫 與超過 500+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

軟體測試是每個軟體工程師都需要掌握的技能,因此我們將陸續來談這個主題,今天這期會先概要介紹軟體測試的測試概覽,大家常聽到的測試金字塔 (Testing Pyramid) 與測試驅動開發 (TDD)。

什麼是測試? 誰該寫測試?

測試是軟體品質與穩定性的把關,確保軟體運行都符合需求,不會出現錯誤。測試的本質之一是找出錯誤,很多人可能會認為程式碼審查(code review) 是在幫忙找錯誤,但先前微軟的研究指出,程式碼審查對協助找出錯誤的幫助有限。比起程式碼審查(code review),測試更能協助找到錯誤,讓軟體上線前能把錯誤都排除,藉此把關軟體品質的存在。

在早期的軟體開發模式中,開發者鮮少需要自己寫測試,在那個年代,幾乎都是由 QA 團隊來負責測試的環節。然而,近年來軟體業界的趨勢有所改變,越來越多團隊發現由開發者負責某部分的測試,對於整體效率、品質都會有所提升。

這與先前在《軟體工程師該如何值班 (on-call)?》一文談到的概念相似,當某個人需要為自己所做的結果負責時,做出的成果品質會比較高,因為如果品質不高,後果不再是由別人幫忙扛,而是自己得負責。

測試就是為軟體的品質把關,所以當測試是由開發者負責,當程式出問題時,就不能甩鍋說是 QA 沒測到。當沒辦法甩鍋,需要自己承擔時,在寫程式就會更加小心謹慎,以免未來的自己要幫現在的自己擦屁股。

雖說現在有不小部分的測試責任,是由開發者自己負責,有些團隊仍會有自動化測試工程師,來協助涵蓋更廣的面向,包含非功能性 (non-functional) 的測試,例如效能、安全性、可用性等面向的測試,甚至是幫忙開發測試使用的模擬伺服器 (mock server)。

測試驅動開發 (Test-driven development)

當談到軟體測試,就不能不談近年來社群中很常會聽到的測試驅動開發 (Test-driven development,俗稱 TDD)。

所謂的 TDD,是指在軟體實際被開發前,就先寫好測試。而這時候,因為還沒有任何實際的程式碼,所以測試都會跑不過;在有了測試後正式進入開發,然後一邊開發一邊通過不同的測試案例,等到所有測試案例都通過後,就算開發完成。

紅燈-綠燈-重構 (Red-Green-Refactor)

當談到 TDD,很常也會聽到紅燈-綠燈-重構 (Red-Green-Refactor) 這個流程。這個流程中有三個重要的元素,分別是:

  • 紅燈:先寫測試,但這時因為還沒有實際的程式,所以程式碼會跑失敗。
  • 綠燈:接著寫能通過測試的程式,這時先不追求程式碼寫多好,能過即可。
  • 重構:最初能通過測試的程式碼,不必然是乾淨好維護的,這時要在能保持測試通過的前提下,重構程式碼,讓程式碼變更乾淨好維護。
紅燈-綠燈-重構
紅燈-綠燈-重構

在這個概念下,很常被忽略的是重構這個步驟,很多人會覺得程式碼都能通過測試就足夠,但是如果沒有去重構、確保程式碼夠好維護,也不能算真的照著 TDD 的精神在走。

這邊的精神是指,TDD 是一種演進的角度看待程式碼,從不能通過測試,到通過測試,再到高品質的程式碼,逐步演進的精神。

是否該採用測試驅動開發?

社群對於 TDD 的採用與否,有很兩極的觀點,有人擁護,也有人認為不該使用。舉例來說,史丹佛電腦科學系教授 John Ousterhout 曾說過自己是測試的擁護者,但是他不認為在軟體開發時該用 TDD。

這是因為他認為,TDD 的做法過度關注在讓功能可以如預期運行,而不是關注在探索最佳的軟體設計方式。

從 TDD 的定義中可以看出,只要最終的功能可以通過所有預先寫好的測試,那就算開發完成,即使後面有重構階段,但這並沒有去規範程式設計上該如何設計,而這正是 John Ousterhout 認為危險的地方。

此外,他認為 TDD 的出發點過於侷限,因為每次關注的點,只在眼前需要通過的測試,而不是從更廣的角度來看整體軟體設計。而他認為,應該要從軟體設計的角度出發,先把軟體設計好後,再來寫測試。

除此之外,假如是在原型開發階段 (prototyping phase),因為功能面都還沒確定下來,且產品與開發團隊仍在探索,這時就相對不適合用 TDD。可以等到探索階段結束後,進到穩定開發階段,再選用 TDD。

不過 John Ousterhout 同時表示,有些情況下 TDD 確實會很有用。具體來說,他認為在修正錯誤 (bug fixing) 時,用 TDD 是不錯的選擇。當程式有錯誤 (bug) 時,就會如 TDD 最開始測試無法通過的狀態;這時先把測試寫好,等同於是在規範程式預期會有什麼樣的行為,而為有在通過這些測試後,才能確保錯誤被修正。可以看到在這種狀況下,TDD 的做法就非常合適。

閱讀更多

如果你對於「軟體測試」這主題感興趣,我們在 E+ 有寫更深入詳細的內容,包含測試金字塔 (Testing Pyramid)、測試金盃 (Testing Trophy) 等主題。有興趣的讀者,歡迎加入 E+ 成長計畫。

本文為 E+ 成長計畫的深度內容,截取前三分之一開放免費閱讀。歡迎加入 E+ 成長計畫閱讀完整版本 (點此了解 E+ 的詳細介紹)

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們