DevOps 与审计 2026年3月26日

2026 指南:在 Mac mini M4 云节点上拆分 iOS UI 测试

NodeMac 团队

移动 CI 专家

发版节奏常被「单机串行跑完所有 UI 测试」拖住。本文说明何时值得分片、用一张矩阵对比单机与多机策略、如何设计 Runner 标签与运行预算,并给出八步清单,把 XCTest UI 工作摊到多台 NodeMac 独占 Mac mini M4 上,让队列可预测。

若已采用 自托管 GitHub Actions macOS Runner,分片是把「一台快 Mac」变成机群的直接手段。构建侧并行可参考 并行 Mac 构建节点与 CI/CD

为何单台强机仍达不到 UI 测试 SLA

Xcode 对单元测试并行很友好,但 UI 测试大量时间花在启动模拟器、动画与 SpringBoard 等待上,单主机上未必随 CPU 核数线性缩短。

  • 模拟器 GPU 争用:同一台 M4 同时跑三套重 UI,帧时间常超过测试隐含的 33 ms 级假设,导致误点与假失败。
  • 磁盘放大:每个分片重复写 DerivedData;SSD 若小于 500 GB 或剩余空间低于约 15%,并行任务易集体崩溃。
  • 队列不透明:无分片标签时,团队分不清慢 PR 是卡在 UI 还是编译,往往超配编译机仍赶不上 UI 截止。

决策矩阵:单机 vs 分片机群

维度 单台 M4 全能机 专用 UI 分片 Mac
90 分钟 UI 总时长墙钟 串行约 90 分钟 3 分片平衡后约 35~40 分钟
抖动敏感 过载时高 单机单套件时更低
运维复杂度 中;需标签与看板
地域建议 任意 港·日·韩·新·美 贴近开发者

扩容前先给用例分桶

分片本质是调度问题。按 p95 耗时把套件分桶,每桶与中位数的偏差尽量控制在 ±20% 内,避免总有一个分片每轮都是长尾。

  1. 从 Xcode Cloud、XCTest 日志或 CI 数据库导出历史耗时,按 p95 排序。
  2. 登录重流程单独成桶,避免阻塞可并行的结账、设置等流。
  3. 需真机实验室的用例单独标记——云 Mac 擅长模拟器,不替代 USB 农场。
  4. 单桶仍超 25 分钟 则按功能模块再拆。
  5. 将分桶映射纳入 Git(如 ui-shards.json)保证可复现。

提示:编译与 UI 分片使用不同标签。混用会导致重型 xcodebuild test 抢走为模拟器预留超时的机器。

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,导致多个分片落到同一 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-* 标签,防止贡献者无意合并并行度。多区域时复制标签族(如 shard-1-sg)使网络路径在 YAML 里一目了然。

在云 Mac mini M4 上落地 UI 分片的八个步骤

假设已通过 SSH 使用 NodeMac 主机,连接说明见 帮助中心

  1. 租用 N 台机器,N = 目标分片数 + 1 台热备用于抖动重跑。
  2. 预装一致 Xcode 与模拟器运行时,避免「只在某分片能通过」。
  3. 注册 GitHub Runner,唯一名称且只挂对应分片标签。
  4. 为工作流设置 timeout-minutes,UI 分片可先设 40 再按 p95 收紧。
  5. 通过 scheme 或 test plan 把分片 ID 传入 xcodebuild-only-testing 列表)。
  6. 关闭显示器睡眠;若 harness 需 GUI 会话,在安全评审中固化策略。
  7. 集中上传 JUnit/截图,文件名带分片名便于排障。
  8. 若某分片连续三轮耗时超其它分片 1.5 倍,重新平衡分桶。

常见问题

一台 Mac mini M4 能跑几个 UI 测试分片?

除非已实测余量,否则将每个重模拟器 UI 分片视为单机单任务;轻量套件可试双分片,但 GPU 与存储争用常抵消墙钟收益。

分片是否应与纯编译任务共用 Runner 标签?

否。使用 ios-ui-shard 等专用标签,避免编译任务占用预装多模拟器、依赖图形会话的机器。

若需在港、日、韩、新、美快速增加分片,请对照 套餐页面 与上文队列估算,避免凭感觉超配或欠配。

Mac mini M4 适合作为 iOS UI 分片单元:Apple Silicon 单线程性能利于 XCTest 编排,统一内存可支撑多模拟器服务,PR 间隙 idle 功耗也相对可控。NodeMac 提供独占物理 Mac mini,支持 SSH 与 VNC,节点覆盖香港、日本、韩国、新加坡与美国,每个分片对应可远程排障的真实硬件。相较一次性采购机柜,按需租用 便于先用真实遥测验证分桶再扩展机群。

为 UI 测试增加专用分片

租用港·日·韩·新·美 Mac mini M4,按分片打标签,缩短 XCTest UI 墙钟。

NM
NodeMac 云 Mac
5分钟部署

云端专属 Apple Silicon Mac,SSH/VNC 随时接入,节点覆盖港·日·新·美。

立即开始