关于 qa-testing-ios
面向 iOS 开发与测试人员的测试执行技能,覆盖 XCTest、XCUITest、Swift Testing 和 Xcode 工具链。重点是控制测试波动,并区分模拟器、真机及发布验证所能证明的范围。
主要功能
- 01运行 iOS 单元、集成与 UI 测试
- 02使用 xcresult 分析测试结果
- 03管理模拟器与真机测试目标
- 04控制波动并隔离测试环境
- 05规划本地化与端到端测试
适用场景
- 01为 PR 配置精简模拟器冒烟测试
- 02定位并复现单个失败测试
- 03验证依赖硬件或分发渠道的功能
- 04为多语言界面规划测试覆盖
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vasilyu1983/ ai-agents-public --skill qa-testing-ios安装后在 Claude Code 中输入/qa-testing-ios确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
learnings.consolidated.mdlearnings.mdagents/openai.yamlassets/template-ios-ui-test-stability-checklist.mddata/sources.jsonreferences/e2e-harness-and-selectors.mdios-ci-general.mdios-ci-github-actions.mdios-version-and-vision-pro.mdsimulator-commands.mdsnapshot-testing-ios.mdswift-testing.mdxctest-patterns.mdxcuitest-patterns.mdscripts/README.mdxcresult_to_junit.pyscripts/tests/test_xcresult_to_junit.pyscripts/tests/fixtures/xcode27_summary.jsonxcode27_tests.json详细介绍
QA 测试(iOS)
为 XCTest、XCUITest、Swift Testing、xcodebuild、xcresult 和 simctl 提供高信号的 iOS 测试执行与不稳定测试控制。
如果工作属于原生 iOS 重写,或 Codex / Claude Code 实现循环的一部分,请将此技能与 software-ios-native 搭配使用。
核心文档:
- https://developer.apple.com/documentation/xctest
- https://developer.apple.com/documentation/testing
- https://developer.apple.com/documentation/xcode/testing-your-apps-in-xcode
- https://developer.apple.com/documentation/xcode/simctl
- https://developer.apple.com/documentation/xcode-release-notes/xcode-27-release-notes
快速参考
| 需求 | 查看 |
|---|---|
| 运行 iOS 测试工作流 | ## Workflow |
| 加载当前默认设置和命令模式 | ## Defaults 和 ## xcodebuild Patterns |
| 控制不稳定测试和目标设备 | ## Flake Control |
| 加载模板和参考资料 | ## Navigation |
发布验证边界
- 如果功能依赖分发签名、真实硬件、APNs、相机、生物识别、购买或后台执行,不要将模拟器测试通过或归档通过视为完整的 iOS 发布证明。
- 对于这些情况,要求采用与生产行为一致的发布路径:已签名的归档、相关的 Beta / 分发渠道验证,以及真实设备上用户可见的结果。
- 不要将项目特定的发布流程、后端端点、测试账号清理和内部运行手册纳入此通用核心内容。请将它们放在项目文档或适用范围明确的参考资料中。
- 发布 CI 和归档路径检查请使用 references/ios-ci-general.md;分发渠道规划请使用 qa-testing-mobile/references/release-and-rollout.md。
默认设置
- 新增单元测试和集成测试:优先使用 Swift Testing,除非项目已统一采用 XCTest。
- UI 测试和性能测试:继续使用 XCTest/XCUITest。
- PR 门禁:使用精简的模拟器冒烟测试,并始终启用
xcresult工件。 - 发布信心:仅在硬件行为相关时增加真实设备测试。
- 不稳定测试的处理原则:先证明测试确实不稳定,再修复隔离、等待或环境漂移问题;重试是调试手段,不是成功标准。
- 自动化必须明确设置区域设置、地区、时区、权限和应用状态。
- 跨框架断言可能因互操作模式而丢失失败信息。切勿假设发现测试就意味着断言兼容;请使用特定版本的模式以及 references/swift-testing.md 中的 CI 检查。
- 采用 iOS 26 SDK 后,请将现有快照基线与 Liquid Glass 渲染效果进行对比,并重新生成受影响的基线。接受前请逐一审查差异。
需要收集的输入
- Xcode 入口:
-workspace或-project -scheme和可选的-testPlan- 目标设备策略:模拟器、真实设备或两者兼用
- 所需钩子:启动参数、启动环境、测试数据、认证绕过、动画开关
- 工件需求:
xcresult、覆盖率、屏幕截图、日志、诊断信息 - CI 环境:本地、GitHub Actions、Xcode Cloud 或可自托管的 macOS
- 是否需要先通过全新卸载、安装和启动来验证,再信任 UI 观察结果
- 任务是否涉及分发渠道或硬件特定行为,需要进行真实设备验证
快速开始
| 命令 | 用途 |
|---|---|
xcodebuild -list -workspace MyApp.xcworkspace | 列出方案 |
xcodebuild -scheme MyApp -showdestinations | 显示有效的目标设备 |
xcodebuild -scheme MyApp -showTestPlans | 显示可用的测试计划 |
xcrun xctrace list devices | 列出实体设备和模拟器 |
xcrun simctl list devices available | 列出可用的模拟器 |
xcrun simctl boot "<simulator-name>" | 启动模拟器 |
xcrun simctl bootstatus booted -b | 等待启动完成 |
xcrun simctl uninstall booted <bundle-id> | 执行冒烟测试前,移除残留的已安装应用 |
在 select-simulator.sh 步骤中,将已启动模拟器的 UDID 保存到 .simulator-udid(已加入 gitignore) | 停止脚本会读取此文件,并调用 xcrun simctl shutdown <UDID> 和 xcrun simctl terminate <UDID> <bundle-id>,准确终止已启动的模拟器。此方案取代 pkill -f Simulator,避免误杀无关的开发/CI 模拟器。UDID 文件是运行脚本与停止脚本之间的约定。 |
xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' -resultBundlePath TestResults.xcresult | 在模拟器上运行测试 |
xcodebuild test -scheme MyApp -destination 'platform=iOS,id=<UDID>' -resultBundlePath TestResults.xcresult | 在设备上运行测试 |
xcodebuild build-for-testing ... 然后运行 xcodebuild test-without-building ... | 更快地重新运行测试 |
xcrun xcresulttool get test-results summary --path TestResults.xcresult | 查看通过/失败情况和数量(使用 get test-results tests 查看测试树)。已弃用的对象 API 需要 --legacy;请查看所选 Xcode 中的 xcrun xcresulttool get object --help |
xcodebuild ... -destination "generic/platform=iOS" build | 不使用模拟器的纯编译构建;模拟器服务不可用或只需证明编译/链接成功时使用 |
xcodebuild archive -scheme MyApp -destination 'generic/platform=iOS' -archivePath MyApp.xcarchive | 验证归档/签名流程(会生成 .xcarchive;-exportArchive 会生成 .ipa)。在宣布候选发布版本就绪前使用 |
工作流
- 首先确定构建输入:工作区或项目、方案、测试计划、目标设备以及所需的启动钩子。
- 确保环境可重复:启动模拟器、设置权限、区域格式、地区,并重置应用状态。
- 如果任务取决于当前二进制文件是否确实显示在屏幕上,请先全新卸载、安装并启动应用,执行冒烟测试,然后再解读屏幕截图或 UI 测试失败。
- 如果模拟器截图路径缺失或已过期,应将其视为工具产物,而非没有证据。请从当前模拟器重新截图,或结合报告的可见症状和源码检查,选择下一项有针对性的检查。
- 如果任务涉及推送、购买、深层链接或其他分发渠道行为,请将传输验证与用户可见结果验证分开;必要时使用实体设备进行验证。
- 将编译、测试、归档、安装/启动、TestFlight 和用户旅程的证据分别记录。记录源码版本、方案/配置、归档或应用标识、目标设备/OS、确切的测试计划或选择器,以及结果包路径;发布声明不得超出最后实际观察到的阶段。
- 运行时启用产物:使用
-resultBundlePath;仅在有助于完成任务时添加覆盖率或诊断信息。 - 先从
xcresult开始排查,再使用-only-testing重现单个失败的测试。 - 如果 CoreSimulatorService 返回 “Connection refused”,不要继续对同一目标设备重试;使用
generic/platform=iOS验证纯编译,并将服务恢复工作交由 software-ios-runtime-debugging 处理。 - 对于依赖后端的流程,请按照 references/e2e-harness-and-selectors.md 中的清单,验证账号重建、缓存隔离以及 Web/API 一致性。
- 将重跑后通过视为不稳定测试;应明确负责人并修复根本原因。
运行时验证边界
- 在应用可构建和安装后,使用此技能处理测试执行、
xcresult、目标设备和不稳定性控制。 - 如果核心问题是安装版本过期、模拟器状态漂移、
.app包格式错误、缺少可执行文件,或安装/启动失败,请转到 software-ios-runtime-debugging。 - 如果应用无法可靠安装或启动,应先将其视为运行时调试问题,其次才是测试问题。
- 模拟器构建或明确未签名的构建无法验证设备签名。开发签名的设备构建可以证明该目标设备的开发签名有效,但无法证明分发签名、导出、TestFlight 处理或发布制品可安装。归档成功本身无法证明导出、安装或启动正常,模拟器测试通过也无法证明 APNs、StoreKit、权利、后台模式、相机、生物识别或其他设备/渠道行为正常。
xcodebuild 模式
# Enumerate before an expensive run
xcodebuild test \
-scheme MyApp \
-testPlan Smoke \
-destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' \
-enumerate-tests \
-test-enumeration-format json
# Target one test
xcodebuild test \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' \
-only-testing:MyAppUITests/LoginFlowTests/testHappyPath \
-resultBundlePath TestResults.xcresult
# Parallelize only when the suite is isolation-safe
xcodebuild test \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' \
-parallel-testing-enabled YES \
-maximum-parallel-testing-workers 4 \
-resultBundlePath TestResults.xcresult
# Controlled retry for CI triage
xcodebuild test \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' \
-retry-tests-on-failure \
-test-iterations 2 \
-test-repetition-relaunch-enabled YES \
-collect-test-diagnostics on-failure \
-resultBundlePath TestResults.xcresult
# Prove a flake locally
xcodebuild test \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' \
-only-testing:MyAppUITests/LoginFlowTests/testHappyPath \
-run-tests-until-failure \
-test-iterations 25
不稳定性控制
- 优先使用
waitForExistence、expectation 和基于状态的断言,而不是休眠等待。 - 在应用允许的情况下,在 UI 测试运行期间禁用或减少动画。
- 为第三方边界提供桩或重定向;UI 测试不要依赖实时外部服务。
- 在测试之间重置权限和应用状态。
- 当断言受区域设置影响时,固定
-testLanguage和-testRegion。 - 使用测试计划,对不同设备类别、区域设置和环境进行矩阵式覆盖。
- 保持 UI 测试套件精简。将大部分业务逻辑覆盖放在较低层。
- 对于多区域设置应用,使用 qa-testing-mobile/references/localization-testing.md 进行分层覆盖。
本地化与视觉回归验证
- 字符串目录或生成的访问器查找中出现缺少键导致的崩溃,是可测试的缺陷,不是可接受的运行时断言。在恢复 UI 润色前,添加或运行目录覆盖测试。
- 验证键是否存在,以及翻译值的质量。对于面向用户的文案,即使区域设置文件包含英文回退值,也仍未通过本地化门禁。
- 为功能添加新的 UI 文案时,先针对每种已发布区域设置检查新增键的键值,再运行覆盖范围更广的静态键测试套件。
- 对高风险区域设置(如德语、俄语、日语和阿拉伯语),将区域设置覆盖与窄屏视觉冒烟测试结合起来。容器宽度、换行和覆盖层遮挡都属于本地化测试,而不是独立的设计润色事项。
- 对于密集的数据可视化屏幕,应进行有针对性的冒烟测试,验证控件、帮助/信息卡片和详情入口不会遮挡主要图表,并且缩放/筛选状态变化后仍可正常使用。
确定性端到端测试框架
对于身份验证、引导、账单和其他与后端耦合的流程,优先使用基于固定数据的启动环境测试框架,而不是实时凭据。明确区分用户变体,在与真实路径相同的函数中保留固定数据分支,并将 .accessibilityIdentifier() 字符串视为测试契约的一部分。
加载 references/e2e-harness-and-selectors.md,了解:
- 标准启动环境固定数据模式
- 测试框架规则和重置钩子的规范
- 标识符与标签的选择器规则
- 引入新端到端测试套件的原子提交模式
- 多账户和后端一致性边缘情况
测试计划组织
Xcode 测试计划(.xctestplan)控制运行哪些测试、使用什么配置以及在哪种环境中运行。使用测试计划管理矩阵式测试执行:
- 冒烟计划:用于 PR 门禁的精简关键路径测试。运行快速、可靠,设备矩阵最小。
- 完整计划:完整的单元测试、集成测试和 UI 测试套件,用于夜间运行或候选发布版本。
- 区域设置计划:相同的 UI 测试,并为每种配置设置不同的
-testLanguage/-testRegion覆盖值。 - 将测试计划与方案一起放在项目目录中。通过 xcodebuild 中的
-testPlan PlanName引用。 - 计划中的每种配置都可以独立覆盖启动参数、环境变量和启用的测试。
- 优先使用多个独立计划,而不是复杂的单个多配置计划——这样更易于运行、分类处理和维护。
iOS 的 AI Agent 测试
AI 原生测试工具(Maestro MCP 等)可补充 XCUITest;用于 PR 门禁的确定性冒烟测试应保留在 XCUITest 中。有关工具定位和决策框架,请加载 qa-testing-mobile/references/ai-native-testing.md。供应商的能力声明变化很快——推荐工具前,请根据供应商当前的文档进行核实。
不适用场景
| 场景 | 改用 |
|---|---|
| 产品架构、应用实现、SwiftUI 重写或 Xcode Agent 工作流 | software-ios-native |
| 构建/安装失败、怀疑应用过期、缺少 bundle 可执行文件,或模拟器/软件包调试 | software-ios-runtime-debugging |
| 跨平台移动测试策略 | qa-testing-mobile |
| 发布版本整体质量策略 | qa-testing-strategy |
资源
| 资源 | 用途 |
|---|---|
| references/e2e-harness-and-selectors.md | 确定性的测试夹具框架、选择器规范和 E2E 上线规则 |
| references/swift-testing.md | Swift Testing 断言、特征、确认、依赖 SDK 的功能以及 XCTest 迁移 |
| references/xctest-patterns.md | 单元测试、集成测试和性能测试的 XCTest 模式 |
| references/xcuitest-patterns.md | XCUITest 编写和不稳定测试控制 |
| references/simulator-commands.md | 自动化中值得使用的当前 simctl 命令 |
| references/snapshot-testing-ios.md | 快照测试及当前注意事项 |
| references/ios-ci-general.md | 不依赖特定提供商的 iOS CI 指南,包括归档路径和全新克隆检查 |
| references/ios-ci-github-actions.md | GitHub Actions 相关细节和运行器变更检查 |
| references/ios-version-and-vision-pro.md | iOS 26 Liquid Glass 对快照的影响、visionOS 26 目标设备语法、Reality Composer Pro 资源测试、手部追踪模拟器限制 |
| ../qa-testing-mobile/references/localization-testing.md | 移动端 UI 和后端提供内容的分层本地化覆盖 |
| ../qa-testing-accessibility/SKILL.md | 无障碍专项 QA 门禁、屏幕阅读器覆盖和符合性边界指南 |
| data/sources.json | 精选外部参考资料 |
脚本
| 脚本 | 用途 |
|---|---|
| scripts/xcresult_to_junit.py | 将 .xcresult 转换为 JUnit XML(Xcode 16+,使用来自 Xcode 27 的测试样例;仅使用标准库)。统计 Test Case 节点,从其子节点读取失败信息;如果统计结果与 xcresulttool get test-results summary 不一致,则退出并返回代码 4。回归测试:python3 -m unittest discover -s scripts/tests |
| scripts/README.md | 使用指南和 CI 集成示例(GitHub Actions、Bitrise) |
模板
| 模板 | 用途 |
|---|---|
| assets/template-ios-ui-test-stability-checklist.md | UI 测试确定性审查清单 |
导航
- 查看
## Workflow、## xcodebuild Patterns和## Flake Control,了解基准流程 - 查看
## Resources和## Templates,了解更深入的资料
经验总结循环
如果以往的决策或陷阱与当前情况相关,请在 learnings.consolidated.md 存在时查阅该文件;仅在需要了解历史记录或将其作为可用备用资料时,才使用 learnings.md。否则跳过这两个文件。
应用后,如果遇到了值得记住的模式、值得避免的错误或令人意外的领域知识,请通过 agents-skills-feedback-loop/scripts/append_learning.py 向 learnings.md 追加一条带日期的项目。不要修改 SKILL.md 本身。