用途
Snap 是一个 XCUITest 专项技能,面向 iOS 应用的 UI 自动化与截图采集。它适用于为 Swift / SwiftUI / UIKit 编写的在售 iOS 应用编写 UI 测试、为登录、结算、引导、设置等关键 iOS UI 流程建立回归覆盖、设计并推行 accessibility identifier 命名体系、在 UI 测试过程中以编程方式截图、搭建面向 App Store 的 fastlane snapshot 截图流水线,以及将 XCUITest 接入 CI 与真机设备云。其范围是纯 iOS:Android UI 测试(Espresso / Compose UI Test)归 Voyager 或 Native,跨平台 E2E 与 Appium / Detox / Maestro 编写归 Voyager,生产 iOS 功能实现归 Native,日志/接口层的单元与集成测试归 Radar,Playwright 网页演示录制归 Director。
主要能力
- XCUITest target 编写:针对在售 iOS 应用编写 UI 测试,建立标识符约定后再构建 Screen Object。
- accessibility identifier 体系设计与审计:以 screen.section.element 约定梳理命名,产出缺失标识符的视图清单,并与 Accessibility Inspector 及录制层级核对。
- 流程回归覆盖:登录、结算、引导、设置等关键用户流程。
- 程序化截图:通过 XCTAttachment 在测试内采集截图,默认失败时附加,检查点截图可选;明确不在 XCUITest 内做像素差异断言。
- App Store 截图流水线:通过 fastlane snapshot 的 Snapfile、SnapshotHelper.swift、专用 Screenshots scheme 与状态栏覆盖脚本,生成多设备、多语言截图,产物进制品库而非主分支。
- Page Object / Screen Object 重构:将录制或既有 XCUITest 代码重构为每屏一个类、暴露用户意图方法、隔离查询链。
- CI 集成:将 xcodebuild test 与结果包接入 Xcode Cloud / GitHub Actions / Bitrise,归档 .xcresult,使用 xcresulttool 转换并可选输出 JUnit。
- 设备农场:通过 build-for-testing 打包 app 与 .xctestrun,上传至 BrowserStack / Sauce Labs / AWS Device Farm 等真机云。
- 结果解析:从 .xcresult 中提取附件、通过数与耗时,锁定 Xcode 大版本或使用 --legacy。
使用方式
技能按 SCOPE → IDENTIFY → AUTHOR → STABILIZE → CAPTURE → REPORT 六个阶段工作:先界定覆盖范围(关键流程、语言与设备矩阵、截图还是回归意图、PR 门禁还是夜间任务),再进行标识符审计与命名体系设计,随后编写测试套件(Screen Object 类、用户意图方法、XCTNSPredicateExpectation 等待、启动参数固定装置),接着消除不稳定因素(通过启动标志关闭动画、播种确定性数据、参数化超时),之后运行截图流水线,最后接入 CI 并解析结果。
技能提供子命令分派:解析用户输入的第一个词,若匹配子命令则激活对应 Recipe 并只加载其「先读」文件,否则走默认的 xcuitest 流程。子命令包括 xcuitest(默认)、identifier、screenshot、appstore、page-object、ci、farm、xcresult。
关键约定:先设计标识符体系,不以标签文本、坐标或元素索引作为主要查询策略,文本匹配仅作为无法标注的系统 UI 的兜底;确定性优先于重试,使用 XCTNSPredicateExpectation + wait(for:timeout:) 而非 Thread.sleep,默认超时 10 秒;通过 app.launchArguments / app.launchEnvironment 在启动时注入固定装置状态,而不是通过 UI 变更应用状态;.xcresult 为事实来源;fastlane snapshot 复用同一测试 target 与 Page Object,但放在独立 scheme 下,避免拖慢 PR CI。
适用场景
- 为在售 iOS 应用编写或扩展 XCUITest target。
- 关键 iOS UI 流程的回归覆盖。
- Swift 代码中标识符分类体系的设计与强制推行。
- UI 测试中的程序化截图(XCTAttachment,分步存证)。
- 跨设备矩阵与语言的 App Store 截图 fastlane snapshot 流水线。
- 通过 xcrun simctl status_bar override 生成干净状态栏的 App Store 截图会话。
- xcodebuild test / test-without-building 调用与结果包解析。
- 录制代码的 Page Object / Screen Object 重构。
- XCUITest 的 CI 集成与真机农场路由。
- Swift 侧快照基线策略(pointfreeco/swift-snapshot-testing 与 XCUITest 截图的取舍)。
限制与边界
- 仅限 iOS:需要 Xcode、Swift / SwiftUI / UIKit 代码库与 XCUITest target;Android 交接给 Voyager。
- 不使用基于坐标的点击作为主要交互方式,仅保留给无法暴露标识符的系统弹窗或画布,并需内联注释说明例外。
- 不使用 Thread.sleep / sleep() 同步;不从 UI 测试中修改启动应用沙箱之外的全局状态(写 UserDefaults、访问实时网络、修改 Keychain)。
- 不将截图输出(Snapshot.images/ 或 fastlane 截图产物)提交到主分支。
- 不忽略 Xcode 版本间 xcresult schema 的破坏性变更。
- 不在与阻塞 PR 的冒烟套件相同的 scheme 中运行 fastlane snapshot(截图运行为 10–30 倍慢)。
- 不将 XCUITest 截图当作正式的视觉回归基线,它们是证据而非基线,基线应用 swift-snapshot-testing 或 App Percy。
- 不在测试中硬编码设备 UDID,应使用 XCUIDevice.shared 并通过 xcodebuild -destination 参数化。
- 需要先询问的情形:视觉回归/像素差异范围不明确时;设备矩阵超过 3 设备 × 3 语言时;要求真机覆盖时需先确认农场厂商与并行会话预算;既有测试 target 缺少标识符约定时;测试需要针对生产构建运行时(涉及签名与描述文件)。
- 若目标应用在测试查询的每个元素上未暴露 accessibility identifier,应先向 Native 或功能负责人提交缺陷,而不是编写脆弱的文本查询。
- 技能提到需对每处代码变更应用 _common/CODE_QUALITY.md 的七轴标准并在完成前输出 CODE_QUALITY_GATE;相关引用文档位于 reference/ 目录下(如 xcuitest-patterns.md、identifier-strategy.md、screenshot-strategies.md、fastlane-snapshot.md、ci-integration.md)。