不只是 TDD #1, 單元測試, 寫出高品質 code 的基本功夫
摘要提示
- 基本功: 提升程式能力的關鍵在於打好資料結構、演算法與測試等基礎
- LeetCode 練功: 把 LeetCode 當成訓練 coding 能力的健身房,專注解題與驗證
- TDD 思維: LeetCode 的測試流程天然符合先寫測試再寫程式的 TDD 核心
- 測試驅動品質: 徹底落實測試能大幅提高 code 品質,為更大規模架構鋪路
- Microservices 前提: 導入微服務前,團隊需具備良好測試與開發流程
- 雲端與測試: 要上雲要先測試的原則同樣適用於微服務與容器時代
- Online Judge 價值: 題庫+測試用例+社群討論,降低入門門檻、聚焦本質
- 正確性與效能: 評量包含正確性、CPU 時間與相對排名,逼迫優化演算法
- 開發環境實作: 將解題流程搬進 Visual Studio,結合 Unit Test 提高效率
- 資料驅動測試: 以 XML 餵測試資料,快速擴充案例並檢視失敗原因
全文重點
作者以多年實務經驗強調:寫好程式必須回到基本功,包括資料結構、演算法與完善的測試。近年他以 LeetCode 作為練功場,因為其題庫與測試案例能讓開發者專注在演算法本質,並在不斷提交與驗證中提升正確性與效能。更進一步,LeetCode 的使用流程其實與 TDD 的精神相符:先有測試(平台提供 test case 與預期結果),後寫程式以通過測試;這對於排斥寫測試的人是最佳的入門切點,能在實作中體會 TDD 帶來的設計與品質收益。
文章把此觀念拉回到現代架構實務:微服務將單體拆成多個獨立服務,對工程素養、版本控管、API 相容性與 Code Quality 要求倍增。若缺乏良好的測試與流程,導入微服務只會放大痛點。作者呼應早年「上雲要先測試」的觀念,指出容器與微服務當道的今日更是如此:想降低部署風險、縮短回歸時間、避免分散式除錯地獄,首要是建立可重複、可自動化的測試體系。
在實作面,作者示範如何把 LeetCode 的解題搬回本機,用 Visual Studio 建立 Class Library 收納解法,再以 Unit Test 對應 LeetCode 的測試行為。先以範例測資寫基本斷言,再升級為資料驅動測試,使用 XML 餵入多組案例,以 Test Manager 檢視每筆結果、執行時間與失敗輸出。如此一來即可在本機快速迭代、觀察效能、逐步改善演算法,最後將一字不改的解答貼回 LeetCode 提交。作者強調環境要極簡、流程要順暢,減少轉貼與手動調整所帶來的摩擦,這與 CI/CD、DevOps 的思路相通:以工具與自動化消除非本質成本,讓開發者專注在設計與解題。
總結來說,本文提供一條務實路徑:用 Online Judge 當作 TDD 的訓練場,在真實的測試束縛與效能排名壓力下鍛鍊程式設計的核心肌群;同時把練功流程內化為日常開發的工程實踐,為雲端與微服務架構奠定可靠的品質基礎。下一篇作者將延伸至多版本自我驗證與執行期驗證,進一步強化可靠度。
段落重點
核心問題: 我為何想要寫這篇?
作者回顧多年教學與工作經驗,指出精進 coding 的答案始終如一:紮實的基本功。透過 LeetCode 練習,比起追逐解題數量或排名,更重要的是在過程中鍛鍊資料結構與演算法,並讓測試成為日常。引用過往系列文與名言強調:工具會更迭,但內功不變。將話題連結到微服務實務:由於系統被拆分,團隊在 code 品質、版本控制、API 相容與流程治理上的要求更高,缺乏基本功的團隊導入微服務只會放大問題。作者呼應「要上雲端,要先測試」的觀念,轉化為「要導入 Microservices,要先測試」,強調測試是現代分散式架構的前提。與其空談 TDD 的好處,不如用 LeetCode 作為切入點,讓開發者在實戰中感受測試驅動的價值,建立持續學習與內化的動機。
番外篇: LeetCode (Online Judge Service) 是啥?
LeetCode 屬於 Online Judge 平台,提供涵蓋演算法、資料庫與腳本的題庫與線上測試功能,並聚合社群討論。其價值在於:讓開發者在低門檻環境中專注本質(演算法與資料結構),不被框架與工具分心;題目搭配可擴充的測試案例與預期結果,天然符合 TDD「先測試、再開發」的流程。平台評量包含正確性、效能(CPU 時間)與相對排名,促使開發者在解題時兼顧時間複雜度與資料結構選擇。以 Two Sum 為例,平台提供題述、範例、線上編輯器與即時 Run/Submit 評分,形成快速回饋迴圈。由於測試案例持續增加且不公開,逼迫開發者回歸「按需求正確實作」的本質,避免投機;同時在比較排名中學習優化,形塑良性競爭與精進。
第一步: 把開發環境搬到 Visual Studio
作者示範將 LeetCode 解題流程遷入 Visual Studio:建立 Class Library 收納題目提供的 Solution 類別,再建立 Unit Test 專案,撰寫對應 LeetCode 範例的斷言,使本機即可重現平台的測試行為。進一步改為資料驅動測試,以 XML (parameters.xml)集中管理多組測資,Test Manager 可逐筆顯示通過與失敗、執行時間與錯誤輸出,利於定位問題與迭代優化。此做法的關鍵是確保本機與平台環境一致,讓解答能「一字不漏」貼回提交,降低手動調整造成的摩擦與錯誤。作者強調環境簡化、流程自動化與可重複,與 CI/CD、DevOps 的理念一致:把非本質工作機械化,讓開發者專注於演算法與設計。本文以此完成練功場的搭建,預告下一篇將延伸至雙版本自我驗證與執行期驗證,強化可靠性與信心。
資訊整理
知識架構圖
- 前置知識:
- 一門主要開發語言(文中以 C# 為例)
- 資料結構與演算法(含時間複雜度觀念)
- 單元測試與 TDD 基本觀念
- 開發工具使用(Visual Studio、MSTest)
- 基本版本控制與開發流程意識(CI/CD、DevOps 的入門概念)
- 核心概念:
- TDD 與測試先行:先有明確的測試案例,再實作與重構,提升可靠度與可維護性
- Online Judge(如 LeetCode)作為 TDD 訓練場:以公共測試案例驅動開發,客觀評估正確性與效能
- 本地化開發環境(VS + Unit Test):把 OJ 流程搬回本地,迭代快、回饋快
- 資料驅動測試(Data-Driven Test):以外部資料(XML)批次驅動測試,提高覆蓋度與可追溯性
- 與微服務實務的關聯:導入微服務前先把測試與品質體系打好,否則複雜度會放大風險
- 技術依賴:
- 題庫與測試案例:LeetCode 的題目與測試數據作為標準規格
- 開發專案結構:Class Library(解題)+ Unit Test Project(測試)
- 測試框架:MSTest([TestClass]、[TestMethod]、[DataSource]、Assert、TestContext)
- 測試資料來源:XML 檔作為輸入/期望輸出對應表
- 持續整合觀念:測試自動化、穩定可重現的環境設定,為 CI/CD 奠基
- 應用場景:
- 面試與演算法熟練度訓練
- 提升日常 coding 基本功與品質(可靠度、可測試性、可維護性)
- 團隊導入微服務/雲端/容器前的品質基線建立
- 建立個人或團隊的測試資料集與回歸測試流程
學習路徑建議
- 入門者路徑:
- 從 LeetCode Easy 題開始,聚焦正確性與基本資料結構
- 學會在 Visual Studio 建立 Unit Test、使用 Assert、閱讀測試輸出
- 練習將題目範例轉為本地單元測試案例
- 進階者路徑:
- 建立「Class Library + Unit Test」的解題模板,做到可直接貼回 OJ 提交
- 使用資料驅動測試(XML/CSV)擴充案例,覆蓋邊界條件
- 引入效能意識:分析時間複雜度、比對不同演算法版本的執行時間
- 實戰路徑:
- 把 TDD 方法用在實際專案功能開發,先寫測試再實作
- 建立自動化測試與 CI 流程(PR 必須通過單元測試)
- 在微服務或雲端部署前,以測試保障 API 相容性與回歸穩定
關鍵要點清單
- 打好基礎而非追新框架:核心在資料結構、演算法與測試思維(優先級: 高)
- TDD 核心流程:Red-Green-Refactor,測試先行驅動設計(優先級: 高)
- LeetCode 作為 TDD 訓練場:公共測試案例與客觀評分機制(優先級: 高)
- 三大評估指標:正確性、效能(CPU time)、相對排名(優先級: 中)
- 時間複雜度意識:選擇合適資料結構與演算法以通過時限(優先級: 高)
- 本地化環境搭建:VS + MSTest,縮短迭代迴圈(優先級: 高)
- 專案分層:解題程式與測試程式分離,提升可測性(優先級: 中)
- 資料驅動測試:以 XML/CSV 驅動多案例,易維護與擴充(優先級: 中)
- 測試輸出與診斷:使用 TestContext/輸出日誌定位失敗案例(優先級: 中)
- 可直接提交的程式骨架:避免提交前手動改動以降低錯誤(優先級: 中)
- 演算法多版本對比:以測試與時間量測比較實作優劣(優先級: 中)
- CI/CD 與 DevOps 思維:穩定可重現的測試流程是自動化基礎(優先級: 中)
- 與微服務的關聯:未先建好測試與品質體系,微服務會放大問題(優先級: 高)
- 社群與題庫價值:多來源 test case 讓覆蓋更完整(優先級: 低)
- 別只追功能與工具:基礎打穩才能在新框架上事半功倍(優先級: 中)