2026 年 iOS PR 流水線在 Mac 雲上跑並行 Simulator 測試:併發、destination 矩陣與磁碟佇列怎麼定
PR 門禁一開啟並行 xcodebuild test,辦公室裡的 Mac mini 池往往先撞上「Simulator 爭用 + DerivedData 暴漲 + 佇列不可見」三件事。本文寫給要把 UI/單測當成可度量 SLA 的讀者:先用三條編號拆解誤區,再給「本機池 vs 可彈性規格 Mac 雲」對照表,隨後給出不少於五步的落地順序、可寫進 Runbook 的併發與磁碟閾值,並以 FAQ 說明何時應先讀本篇、何時直接開啟站內 90 秒 API 開通與 CI 對接或 構建佇列與 DerivedData長文。
本文要點
1. 三類痛點:把 Simulator 當「輕量容器」
多數團隊已在 Linux 上跑完靜態分析與單測骨架,真正拖慢合併頻率的,往往是 macOS 上的 Simulator 級測試。習慣「像管 VPS 一樣」用 SSH 管機器的人,最容易在 PR 場景裡低估下面三類成本。
- 把並行 worker 當成線性擴容:同一臺機器上盲目提高
-parallel-testing-enabled或 fork 多個 destination,會讓 CPU 搶佔與 I/O 抖動疊加,反而拉長尾延遲;沒有「每核可承載的 Simulator 數」這類內部基線,SLA 只能寫成口號。 - destination 矩陣複製生產「全機型」到每個 PR:全矩陣在釋出周有意義,在 PR 門禁裡常常浪費;未區分「阻斷類」與「資訊類」目的地,會讓佇列深度在高峰線性爆炸。
- DerivedData 與測試附件當軟預算:錄屏、失敗快照、效能軌跡預設開啟時,單 PR 可在數小時內吃掉數十 GB;若清理策略只在週末跑一次,週三下午磁碟就會先於業務掛掉。站內 構建佇列與 DerivedData一文從構建側講過水位,本篇把同一邏輯收緊到「PR 高頻短 Job」。
先把「併發上限、destination 子集、磁碟迴收」三件事引數化,再談工具鏈版本。
2. 對照表:本機 Mac 池與 Mac 雲 PR 節點
下表用於評審第一版:左側是常見訴求,右側給出推薦形態與主要風險。
| 訴求 | 辦公室 Mac mini 池 | 規格可預期的 Mac 雲 PR 節點 | 備註 |
|---|---|---|---|
| 峰值併發可預測 | 受桌面佔用、系統更新與人工登入影響大 | 機型與記憶體釘死,適合把併發寫成程式碼 | 與 GitHub 託管 Runner 對比見 自建池對照文 |
| 磁碟水位 | 共享盤易「誰都沒刪」 | 按 Job 掛載臨時卷或強制定時 prune | 建議 PR Job 結束即刪 DerivedData 子樹 |
| 佇列可見性 | 常靠口頭協調 | 與 CI 標籤、API 擴容一致 | 參見 可觀測性清單 |
| 網路 RTT | 內網低但拓撲復雜 | 可選區域,貼近程式碼與製品庫 | 與跨端混合流水線可組合閱讀 |
3. 七步落地:併發、destination 與清理
- 建立「每機型 Simulator 數 × 並行測試 worker」基線表:在目標機型上用典型工程跑 20 次 PR 長度任務,記錄 P95 時長與峰值 RSS,得到「每物理核最多併發幾個 Simulator」初值。
- 把 destination 分成阻斷集與擴充套件集:阻斷集只保留最新兩代 iOS 與主螢幕尺寸;擴充套件集 nightly 再跑,PR 失敗不阻斷合併。
- 為
xcodebuild test設定硬超時與分層重試:基礎設施超時與斷言失敗分流;對 flaky UI 用「同 commit 最多重試 1 次」策略並打標籤,避免無限重跑掩蓋佇列問題。 - 在 Job 尾部掛清理鉤子:無論成功失敗執行
xcrun simctl shutdown all與 DerivedData 子目錄刪除;對附件大於閾值的結果包做截斷上傳。 - 把佇列深度暴露成指標:在 CI 平臺記錄「等待 macOS 執行器」的排隊時間分佈,超過閾值自動擴容或降級 destination。
- 與 Linux 前置 Job 約定 artifact 邊界:只傳編譯產物與索引,不傳整倉 Pods 快取除非命中籤名。
- 寫一頁 Runbook:包含「磁碟>某閾值→只跑阻斷集」「佇列>某深度→禁止擴充套件集」的開關語句,值班可照抄執行。
4. 可引用閾值:CPU、磁碟與佇列深度
下列數字用於評審對齊,最終以你們工程實測為準:① 在 M4 級約 10~12 核可見算力、32GB 記憶體的節點上,常見消費級 App 的 PR 阻斷集可先從「並行 worker 3~4 + 同時活躍 Simulator ≤4」起評,再按 UI 用例密度上調或下調。② 單 PR Job 建議預留約 1.8~2.4 倍最近一次成功構建的 DerivedData 體積作為磁碟峰值,低於全域剩餘空間 12% 時觸發只跑阻斷集策略。③ 佇列深度若連續 30 分鐘高於「可用 macOS 執行器」數量的 4 倍,應優先降級擴展集而非盲目加機器,否則會把 flaky 放大成全隊噪聲。④ 錄屏與效能軌跡建議預設關閉於 PR,僅在手動觸發或 nightly 開啟,可把附件體積從數 GB 壓到數百 MB 量級。⑤ 合併到主分支後保留一次完整矩陣結果 JSON 24~72 小時,便於對比「PR 窄集透過但寬集失敗」的迴歸型別。
5. 常見問題
PR 要不要跑 iPad 與多系統_minor 全排列?
不建議預設全排列;用阻斷集覆蓋最新使用者佔比高的機型,其餘放 nightly 或釋出分支。
並行一開啟就隨機卡死怎麼辦?
先減半 worker 並關閉錄屏;檢查是否多個 Job 共享同一使用者會話導致 Simulator 鎖爭用。
與「90 秒開通 Mac 雲」文件如何分工?
該文講資源入口與 Runner 註冊;本文講跑起來之後如何把 Simulator 與磁碟治理到可釋出狀態。
6. 從 PR 測試回到可預期的 Mac 執行面
只在辦公室堆幾臺 Mac mini 能撐過早期迭代,但一旦 PR 頻率與並行度上來,人力擦盤與口頭協調會迅速成為隱藏單點:尾延遲不可解釋,佇列深度不可見,夜間合併仍靠賭磁碟餘量。純筆記本環境又缺持續電源與穩定上行,和「像管 VPS 一樣」的運維習慣也不一致。若要把 PR 門禁做成可度量、可降級、可擴容的流水線,租賃 VPSMAC 的 M4 Mac 雲主機作為專用 PR 執行池,通常比在混雜桌面或超售共享環境裡硬扛更穩:SSH 與標籤體系與 Linux 排程器一致,機型與記憶體可釘死,清理與併發策略可寫進同一套 Runbook,並與站內 API 開通、DerivedData 佇列及 Runner 對照文形成閉環。