儘管 Swift 已成為主流,但許多核心業務、底層框架與大型存量項目仍然以 Objective-C(OC) 作為開發主語言。 而 OC 的動態性(Runtime)、消息派發機制、內存模型(ARC)、KVO/KVC 特性也使其在測試環節擁有更高要求: 功能正確性要更嚴格、內存管理要更精確、性能測試必須更全面、系統行為更需關注。
因此,真正的 OC 測試體系從來不是“寫幾個單測”或“點點 UI 流程”,而是一個由 功能測試 + 性能測試 + 內存分析 + 系統日誌驗證 + 多工具協同調試 組成的完整鏈路。
本文結合 XCTest、OCMock、Instruments、克魔(KeyMob)、PerfDog、Xcode 調試器、Charles、Safari Inspector、Crashlytics、MetricKit 構建一套現代化的 Objective-C 測試體系。
一、為什麼 OC 測試比想象中更復雜?
OC 的動態特性決定了它的測試重點與 Swift 不太一樣:
1. Runtime 行為強依賴測試覆蓋
- method swizzling
- 動態轉發
- 消息派發優化
- 類簇設計(Class Cluster)
2. 內存模型可預測性弱於 Swift
- block 循環引用
- weak / strong 跨線程訪問
- KVO 未移除導致崩潰
- delegate 未釋放導致內存增長
3. OC 更依賴多線程測試
- GCD
- NSOperationQueue
- RunLoop 行為
- Timer 生命週期
4. UI 使用純代碼,佈局問題更易隱藏
因此 OC 測試必須覆蓋:
- 功能
- 性能
- 內存
- 系統行為
- 異常恢復
- WebView / 網絡鏈路
- 上線診斷
這也是多工具協同的必要性。
二、OC 功能測試的基礎:XCTest + OCMock
1. XCTest(單元測試與集成測試)
適用於:
- Model 層邏輯
- 工具類
- 算法
- 數據處理
- 網絡請求內部邏輯
OC 單元測試建議重點放在純邏輯部分,而非 UI 部分。
2. OCMock(對象替身)
可用於模擬:
- 網絡層
- 數據返回
- 外部依賴行為
- Delegate 回調
在 OC 中,由於協議回調廣泛使用,OCMock 能大幅提升測試效率。
三、Xcode 調試工具:OC 代碼執行行為的第一觀察層
1. LLDB(斷點調試)
常用於:
- 調試消息派發順序
- 檢查對象釋放情況
- 驗證 ARC 行為
2. Memory Graph Debugger(內存圖)
可以看到:
- 循環引用
- 控制器未釋放
- Block 鎖定對象
對 OC 來説非常重要,因為 ARC 不會自動解決循環引用問題。
四、Instruments:OC 性能測試的核心武器
OC 代碼因消息派發、動態綁定等機制使其在性能分析中需要更精確的工具,而 Instruments 是第一選擇。
1. Time Profiler(CPU 分析)
適用於:
- 查找頻繁調用的方法
- 定位耗時循環
- 分析主線程阻塞
在大量 OC 代碼的工程中,Method Dispatch 是常見性能瓶頸。
2. Allocations / Leaks(內存分析)
可檢測:
- NSDictionary/NSArray 的大規模創建
- Runtime 動態對象產生的臨時對象
- 控制器未釋放
OC 使用者最擔心的問題就是:退出頁面內存不下降。
3. Zombies(對象訪問錯誤)
用於定位:
- 訪問已釋放對象
- KVO 未移除導致的異常
這些錯誤在 OC 中非常常見且隱蔽。
五、克魔(KeyMob):真機行為驗證 + 系統日誌是 OC 測試的關鍵補充
OC 項目的穩定性很大程度上取決於系統行為與真機表現。 KeyMob 可以補齊 Instruments 的短板:
1. 真機性能監控(CPU / GPU / 內存 / FPS)
適合 OC 常見場景:
- 列表滾動卡頓
- 動畫掉幀
- 頁面多次進入退出
- 長時間運行導致內存上漲
2. 系統日誌是 OC 測試中極其重要的部分
OC 常見錯誤會在系統日誌中體現,例如:
KVO crash
object deallocated while key value observers still registered
EXC_BAD_ACCESS
malloc_error
jetsam (內存壓力)
watchdog (主線程卡死)
這些信息 Xcode 無法完整呈現,而 KeyMob 能抓全量。
六、PerfDog:OC UI 層性能的高精度測試工具
OC 多用於成熟項目,其中 UI 常非常複雜,PerfDog 在以下方面表現突出:
- FPS 曲線
- GPU 壓力
- 列表滾動性能
- 動畫執行性能
- 長時間運行的內存趨勢
OC 工程中常見“寫得很巧妙”的 UI 動畫,其實性能消耗很大,PerfDog 能清楚暴露這些問題。
七、Charles:OC 網絡行為測試的必要工具
OC 項目網絡層多數基於:
- AFNetworking
- NSURLSession
Charles 可用於檢測:
- 弱網下的性能表現
- 隊列併發導致的性能壓力
- 數據包過大導致 CPU/內存上升
- 多次重試導致資源佔用
許多 OC 項目的性能問題源於“網絡層處理不當”。
八、Safari Inspector:OC + WebView 項目必測環節
大量 OC 項目仍然嵌入 Hybrid,例如:
- UIWebView(歷史項目遺留)
- WKWebView
- 業務活動頁
- uni-app 頁面
Safari Inspector 能檢測:
- JS 執行是否阻塞主線程
- DOM 是否過大
- 資源加載是否合理
- JSBridge 是否過度調用
OC 與 Hybrid 常見的問題常常是“二者交互效率低”,此工具必不可少。
九、MetricKit:OC 項目上線後的性能診斷核心
MetricKit 可提供:
- OOM(內存壓力殺)
- CPU 峯值
- I/O 耗時
- 啓動時間
- WebKit 崩潰
- 主線程卡頓(hang diagnostics)
OC 項目的複雜程度通常較高,因此版本趨勢尤為重要。
十、Crashlytics:OC 運行行為異常的重要補充
Crashlytics 負責捕獲“線上真實用户場景”中的異常行為,包括:
- EXC_BAD_ACCESS
- KVO 崩潰
- 數組越界
- 多線程訪問錯誤
- 死鎖/卡住
- 被系統殺死前後的線程狀態
OC 的動態性決定了 Crashlytics 數據比 Swift 項目更有價值。
十一、構建完整的 OC 測試工具矩陣
| 測試維度 | 工具組合 | 適用場景 |
|---|---|---|
| 功能測試 | XCTest + OCMock | 業務邏輯 |
| CPU 性能 | Instruments + KeyMob | 熱點、阻塞 |
| UI 性能 | PerfDog + Core Animation | 掉幀、動畫 |
| 內存問題 | Leaks + KeyMob + Zombies | 泄漏、釋放錯誤 |
| Hybrid 性能 | Safari Inspector | JS/DOM/資源 |
| 網絡性能 | Charles + KeyMob | 弱網、超時 |
| 穩定性 | MetricKit + Crashlytics | 線上趨勢 |
這是可落地、工程化的 OC 測試體系。
OC 測試不是“老項目維護”,而是工程能力的體現
優秀的 Objective-C 測試體系必須具備:
可觀測 → 可定位 → 可量化 → 可復現 → 可迴歸 → 可監控
而要做到這一點,需要以下工具鏈協同:
- XCTest、OCMock(邏輯測試)
- Instruments(深度 CPU/內存分析)
- KeyMob(真機性能 + 系統日誌)
- PerfDog(UI 流暢度與長時間測試)
- Safari Inspector(WebView 測試)
- Charles(網絡測試)
- MetricKit / Crashlytics(上線表現)
這就是完整的 OC 測試體系。