DevOps 與稽核 2026年3月26日

2026 指南:在 Mac mini M4 雲端節點上分片執行 iOS UI 測試

NodeMac Team

行動 CI 專家

當單一 Mac 以序列方式跑完所有 UI 測試時,行動版發佈節奏往往卡住。本篇說明何時值得分片、如何在同一決策矩陣中比較單機與多機策略、如何定義 Runner 標籤與執行時間預算,並以八個具體步驟將 XCTest UI 工作分散到專用的 Mac mini M4 雲端主機上,讓佇列數學可預測。

若您正在標準化 自架 GitHub Actions Runner,分片就是把「一台很快的 Mac」變成能在審核者切換情境前完成 PR 驗證的機隊。若要更廣泛的建置平行度,亦可參考 CI/CD 用的平行 Mac 建置節點

為何一台強力 Mac 仍打不到 UI 測試 SLA

Xcode 能積極平行化單元測試,但 UI 測試會耗在啟動模擬器、動畫轉場與等待 SpringBoard—這類工作在同一台主機上並不會隨 CPU 核心數線性擴展。

  • 模擬器 GPU 競爭:在單一 M4 上同時跑三套 UI 套件時,影格時間常超過測試隱含假設的 33 ms 門檻,導致點擊不穩與誤判失敗。
  • 磁碟放大效應:每個分片都會重複寫入 DerivedData;若沒有 500 GB 以上 SSD 餘裕,平行工作會在可用空間低於約 15% 時集體崩潰。
  • 佇列不透明:沒有每分片標籤的團隊無法判斷慢 PR 是在等 UI 基礎設施還是編譯佇列—結果過度配置編譯 Runner 仍錯過 UI 截止時間。

決策矩陣:單機 Mac 與分片機隊

準則 單一 M4「包辦一切」 專用 UI 分片 Mac
90 分鐘 UI 套件的牆鐘時間 序列 ≈ 90 分鐘 3 分片且平衡時 ≈ 35–40 分鐘
不穩定敏感度 過載時偏高 每機一套套件時較低
維運複雜度 中;需標籤與儀表板
最佳地理配置 任意 將分片放在港/日/韓/新/美,貼近開發者

採購前先為測試分桶

分片本質是排程問題偽裝成基礎設施。請將套件切成執行時間變異相近的桶—目標是每桶落在時長中位數的 ±20% 內,避免永遠同一分片當落後者。

  1. 匯出歷史耗時自 Xcode Cloud、XCTest 日誌或 CI 資料庫;依 p95 時長排序測試。
  2. 將登入密集流程獨立成桶,以免阻塞可獨立執行的結帳或設定流程。
  3. 需實體裝置實驗室的測試另打標—雲端 Mac mini 擅長模擬器,而非 USB 連接的硬體農場。
  4. 限制桶大小使每桶在 PR 預算內完成;若仍超過 25 分鐘,再依功能模組拆分。
  5. 將分桶對照表納入 gitui-shards.json)以利重跑可重現。

提示:編譯與 UI 分片請使用不同標籤。混用會在沉重的 xcodebuild test 搶走為模擬器設好逾時的 UI 機器時,造成佇列反轉意外。

UI 分片的 Runner 標籤契約

標籤組 用途 runs-on 範例
self-hosted, macOS, m4, ios-compile 僅建置與單元測試 [self-hosted, macOS, m4, ios-compile]
self-hosted, macOS, m4, ios-ui, shard-1 UI 桶 A [self-hosted, macOS, m4, ios-ui, shard-1]
self-hosted, macOS, m4, ios-ui, shard-2 UI 桶 B 對 B/C/D… 採相同模式

GitHub Actions 矩陣:避免意外重複排程

多數團隊以矩陣維度表達分片。失敗模式是同時宣告 shard: [1,2,3] 與過寬的 runs-on 標籤以致匹配每台 Mac—GitHub 可能把多個分片排在同一主機,讓硬體投資白費。請將每個矩陣分支鎖到唯一 Runner 標籤,或使用與主機名一對一的儲存庫變數。

strategy:
  matrix:
    shard: [1, 2, 3]
    include:
      - shard: 1
        runner_labels: [self-hosted, macOS, m4, ios-ui, shard-1]
      - shard: 2
        runner_labels: [self-hosted, macOS, m4, ios-ui, shard-2]
      - shard: 3
        runner_labels: [self-hosted, macOS, m4, ios-ui, shard-3]
jobs:
  ui-tests:
    runs-on: ${{ matrix.runner_labels }}
    timeout-minutes: 40

搭配儲存庫規則,拒絕 UI 工作缺少 shard-* 標籤的流程;單一政策即可防止善意貢獻者意外壓扁平行度。當您在第二區域(例如新加坡運算搭配東京審核者)加租 Mac mini 時,請按區域複製標籤方案(shard-1-sg),讓網路鄰近在 YAML 中一目了然。

在雲端 Mac mini M4 上啟用 UI 分片的八步驟

以下假設您可透過 SSH 連線至 NodeMac 的 Mac mini M4 主機。連線方式請見 說明中心

  1. 開通 N 台機器,N 等於目標分片數加 台熱備以應對不穩重跑。
  2. 預裝相同版號的 Xcode 與模擬器 runtime;分片間漂移會造成「在我的 Runner 上可以」的假陰性。
  3. 註冊 GitHub Runner 時使用唯一名稱,且僅掛上該分片應服務的標籤。
  4. 為每個工作流程設定 timeout-minutes—UI 分片可先從 40 分鐘起,再依 p95 收緊。
  5. 將分片識別傳入 xcodebuild(透過 scheme 或測試計畫,每桶使用 -only-testing 清單)。
  6. 關閉螢幕睡眠,若測試架構需要 GUI 工作階段則確保 CI 使用者保持登入;並依資安審查記錄政策。
  7. 集中上傳產物(JUnit、截圖),檔名含分片名稱以利分診。
  8. 分片傾斜告警:若某分片連續三次執行比其他分片慢 1.5 倍 以上,請重新平衡桶。

常見問題

一台 Mac mini M4 能容納多少個 UI 測試分片?

除非已量測到剩餘容量,否則將每個重度依賴模擬器的 UI 分片視為每台機器一個主要工作;輕量套件可嘗試兩個分片,但 GPU 與儲存競爭常會抵銷牆鐘時間的改善。

分片是否應與僅編譯工作使用相同的 Runner 標籤?

不應如此—請使用專用標籤,例如 ios-ui-shard,讓編譯工作不會搶走已額外配置模擬器與螢幕工作階段假設的機器。

若您需要距香港、東京、首爾、新加坡或美國團隊僅數分鐘路程的機器,請對照 NodeMac 方案,依上文佇列數學對齊分片數量,而非憑感覺猜測。

Mac mini M4 是 iOS UI 工作的實用分片單元:Apple Silicon 為 XCTest 編排提供強勁單執行緒效能、統一記憶體可支撐多個模擬器服務,且在 Runner 等待 PR 空檔時待機功耗低。NodeMac 出租 專用實體 Mac mini,於港、日、韓、新、美提供 SSH 與 VNC—每個分片對應可遠端除錯的真實硬體。相較買滿一整櫃 Mac,按需租用 可在驗證分片地圖與依實際遙測重新平衡時壓低資本支出。

新增專用 UI 測試分片

於港·日·韓·新·美租用 Mac mini M4 節點,依分片標記 Runner,以可預測的佇列縮短 XCTest UI 牆鐘時間。

NM
NodeMac Cloud Mac
5分鐘部署

雲端專屬 Apple Silicon Mac,SSH/VNC 隨時接入,節點覆蓋港·日·新·美。

立即開始