核心理念:好程式是「測」出來的
C++ 世界沒有 GC 安全網,記憶體洩漏、野指標、競態條件隨時可能引發災難。本文系統化呈現一套經驗驗證的 C++ Server 測試體系,涵蓋開發期、白盒、記憶體、壓力、穩定性、覆蓋率、效能七大階段。
階段一:開發期單元測試 —— CppUnit
- 針對解析類、演算法類等邏輯獨立模組。
- 目錄結構:`src/` 存放產品碼,`test/` 存放測試碼,含 `testClass1.h`、`test.cpp`、`Makefile`。
- 關鍵巨集:`CPPUNIT_TEST_SUITE`、`CPPUNIT_TEST`、`CPPUNIT_ASSERT_EQUAL`。
- 持續整合:每次提交自動編譯運行測試,保證核心邏輯零錯誤。
階段二:白盒功能邏輯測試
- 驗證所有資料結構按規格變化、多執行緒狀態一致性。
- 可插桩代碼(宏開關/互動指令)觀察內部狀態。
- 目標:功能覆蓋率 100%,零邏輯錯誤。
階段三:記憶體檢測 —— Valgrind Memcheck
valgrind --tool=memcheck -v --leak-check=full ./server_binary
- 檢測顯性洩漏、無效讀寫、未初始化值使用。
- 單路客戶端陪測下,要求零洩漏、零記憶體錯誤。
階段四:批量客戶端模擬器(Perl 推薦)
- 腳本語言開發快、Socket API 簡單。
- 配置檔驅動:定義 IP、Port、URL、信令序列(如 `
` 表示發送 SETUP 後 sleep 2s)。
- 進階版:多進程並發、混合配置、隨機斷線、持續殺掉重啟迴圈,模擬真實混沌環境。
階段五:壓力下的記憶體驗證
- Valgrind + 批量腳本同跑。
- 指標:無異常狀態、資料一致、零洩漏、零讀寫錯誤。
階段六:長時間穩定性與洩漏測試
- 數百路客戶端,CPU 佔用 70%+,持續 20+ 小時。
- 監控進程 RSS/VSZ 曲線:必須平穩,不可隨時間單調增長。
- 通過標準:不崩潰、無洩漏。
階段七:代碼覆蓋率 —— Gcov
- GCC 內建,編譯加 `-fprofile-arcs -ftest-coverage`,運行生成 `.gcda`,用 `gcov` 或 `lcov` 產生報表。
- 迭代修正腳本,覆蓋邊界分支、錯誤路徑。
- 執行頻次高的熱點函數,也是效能優化切入點。
階段八:效能剖析 —— Gprof
- 編譯加 `-pg`,運行生成 `gmon.out`,`gprof` 輸出函數級耗時排序。
- 多數瓶頸歸結於資料結構選型與演算法複雜度,而非語言細節。
鐵律:任何 Core Dump / 記憶體錯誤 必須歸零
墨菲定律在 C++ 面前無情兌現:測試階段未修復的微小 Bug,上線後必演變成重大事故。以「零容忍」態度對待每一次 sanitizer 報警,才是對使用者負責的表現。