Skip to content

[iOS][XCUITest] RemoteControlTest 系统数据暴涨原因与 WDA 对比 #59

Description

@nzcv

[iOS][XCUITest] RemoteControlTest 系统数据暴涨原因与 WDA 对比

对比自研 RemoteControlTest(XCUITest + swifter HTTP 常驻 Runner)与官方 Appium WebDriverAgent,分析为何前者会在 iPhone「系统数据」中持续占用大量空间,而后者几乎不明显。

核心结论

两者虽然都是「设备上跑 XCTest + HTTP 远程控制」,但数据落盘策略会话形态差异很大:

维度 RemoteControlTest 官方 WebDriverAgent
会话时长 单次最长 6 小时MAX_SESSION_SECONDS 常驻但轻量,很少长时间积累
截图 写到设备 tmp/RemoteControlScreenshots/,默认最多 200 张全屏 PNG 只通过 HTTP 返回,不写设备磁盘
内存测量 XCTMemoryMetric 会把 memgraph 写进 .xcresult 没有这类功能
测试附件 xctestplanuserAttachmentLifetime: keepAlways 基本不产生用户附件
启动方式 xcodebuild test-without-building 整条测试链路常驻 通常 go-ios runwda 等轻量启动

iOS 设置里的「系统数据」会把 XCTest 诊断数据、开发者日志、tmp 缓存、测试结果包 都算进去。RemoteControlTest 在这些方面都比 WDA「重」得多。

具体会在设备上写什么

1. 截图持续落盘(最大头之一)

captureScreenshot() 会:

  • 调用 XCUIScreen.main.screenshot() 取全屏 PNG
  • 写入 FileManager.default.temporaryDirectory/RemoteControlScreenshots/
  • 通过 pruneDeviceScreenshots() 保留最多 MAX_DEVICE_SCREENSHOTS(默认 200)张

如果开启 /api/screenshot/start?interval=1&limit=0(无限定时截图),设备上会长期维持最多 200 张全屏 PNG。一张通常 1–3 MB,光这个目录就可能占 几百 MB

WDA 的截图是按需取、经网络拿走,不在设备上留文件

2. 长时间 XCUITest 会话持续积累 .xcresult

testRemoteControl() 是一个永不结束的主循环(最长 6 小时),期间 XCTest 会在设备侧持续积累:

  • testmanagerd / DTServiceHub 日志
  • UI 层级查询缓存(权限弹窗轮询每 1.5 秒扫一次 SpringBoard)
  • 测试结果包相关数据

WDA 虽然也常驻,但交互更「薄」:主要是 tap/swipe/screenshot,没有定时截图落盘、没有内存图、没有长时间 measure 窗口

3. XCTMemoryMetric 会产生很大的 memgraph 附件

/api/measuring/* 调用 measure(metrics: [XCTMemoryMetric(application: app)]),XCTest 会把应用的 内存快照(memgraph) 写进 .xcresult。单个快照可达 几十到上百 MB

RemoteControlTest.xctestplan 配置:

"defaultOptions": {
  "preferredScreenCaptureFormat": "screenshot",
  "uiTestingScreenshotsLifetime": "keepNever",
  "userAttachmentLifetime": "keepAlways"
}

userAttachmentLifetime: keepAlways 意味着这些附件一直留在结果包里,不会被自动清理。WDA 完全没有这条路径。

4. 截图 attachment 默认已关闭

代码里 ATTACH_SCREENSHOTS 默认 false,截图不会 attach 到 .xcresult(README 有一处过时描述仍写会 attach)。真正占空间的主要是:tmp 截图目录 + xcresult 里的 memgraph + XCTest 系统日志

相关代码注释:

/// It is *not* attached to the test result bundle by default:
/// `XCTAttachment`s live for the whole (multi-hour) session and never get a
/// chance to be pruned before the runner exits, so keeping every screenshot
/// would inflate the on-device result bundle (and iOS "System Data") without
/// bound.

为什么 WDA 看起来「不产生系统数据」

WDA 的设计目标是远程控制代理,不是长时间数据采集器

  1. 截图 → 内存 → HTTP 响应,不落盘
  2. 没有定时截图、没有 memgraph 导出
  3. 会话相对轻,XCTest 基础设施产生的日志/缓存更少
  4. 很多团队会定期重启 WDA,设备上的临时数据会被系统回收

RemoteControlTest 更像是「远程控制 + 持续截图 + 内存分析」的重型测试 Runner,天然会比 WDA 多占「系统数据」。

减少系统数据的建议

  1. 不要长期开定时截图,或把 MAX_DEVICE_SCREENSHOTS 调小(如 20
  2. 少用 /api/measuring/*,memgraph 是体积最大的来源之一
  3. 确认没有设置 ATTACH_SCREENSHOTS=1
  4. 定期调用 /api/exit 结束会话,让 XCTest 正常收尾(比强杀进程更容易释放)
  5. 开发机上定期清理:Xcode → Devices → 选设备 → 查看/删除测试数据;或在设备上重启
  6. 如果不需要设备本地留截图副本,可以改成只走 HTTP 返回、不写 RemoteControlScreenshots 目录(和 WDA 对齐)

推荐组合

  • 日常远程控制:避免 screenshot/start 无限模式;截图只通过 HTTP 拉取,不落盘
  • 内存分析场景:用完 measuring 后及时 /api/exit 结束会话,并导出 .xcresult 后清理设备测试数据
  • 对标 WDA 的轻量模式:截图不写 tmp、不开 measuring、缩短 MAX_SESSION_SECONDS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions