Developer Tools 进阶 20m
为 Xcode Cloud 编写快速可靠的测试
Author fast and reliable tests for Xcode Cloud
2022年6月6日
一句话判断
测试在 CI 中不稳定?这场 Session 给出了从模拟器配置、环境变量管理到 XCTSkip 和 XCTExpectFailure 的完整解决方案。
这场 Session 讲了什么
Xcode Cloud 的核心优势是把测试扩展到更多目标设备、更多 OS 版本、更多配置组合。但测试数量增加后,可靠性问题会指数级放大——一个偶尔失败的测试在本地可能不明显,在每天跑几十次的 CI 上就是灾难。
Session 围绕 Food Truck 示例 App,系统性地解决了四类测试可靠性问题。第一,模拟器环境假设:时区、语言、权限、预置数据这些本地开发时习以为常的设置,在 CI 的全新模拟器上可能完全不同。第二,测试前置条件处理:用 XCTSkip 优雅地跳过不满足条件的测试,而不是让它失败。第三,超时问题:用 async/await 替代 XCTestExpectation 的超时机制。第四,已知失败的管理:用 XCTExpectFailure 标记预期中的失败,避免噪声。
值得深挖的点
- 模拟器环境假设清单:时区(服务器可能在不同时区)、Locale(数字格式和文字方向)、权限(网络、相机等需要 mock 或用 alert handler)、预置数据(推荐在 setUp 中生成 mock 数据而非依赖 tearDown)。这份清单值得每个做 CI 的团队对照检查。
- 环境变量传递机制:Xcode Cloud 中以
TEST_RUNNER_为前缀的环境变量会自动传递给测试 Runner。比如TEST_RUNNER_BASE_URL在测试代码中变为BASE_URL。可以在 Workflow 设置或 Test Plan 中配置。 - XCTExpectFailure 的妙用:当某个测试依赖的外部服务(如 staging 服务器)不可用时,用
XCTExpectFailure标记而不是跳过。测试仍然会执行,如果确实失败了会被标记为”expected failure”而不是报错;如果意外通过了,反而会提醒你可能需要移除这个标记。 - async/await 替代超时:
XCTestExpectation的超时时间很难调——太短偶尔失败,太长浪费时间。用 async/await 可以让测试自然等待,不需要猜超时值。
代码片段
// 用环境变量控制测试行为
func testOrderDonut() throws {
let env = ProcessInfo.processInfo.environment
let baseURL = env["BASE_URL"] ?? "https://staging.example.com"
// 在生产环境跳过这个测试
if env["ENVIRONMENT"] == "production" {
XCTSkip("不在生产环境执行真实下单测试")
}
// 正常测试逻辑...
}
// 用 XCTExpectFailure 处理已知问题
func testStagingServiceIntegration() throws {
XCTExpectFailure("Staging 服务器正在维护,预计会失败")
let result = try apiClient.fetchData()
// 如果失败 → 标记为 expected failure,不阻塞 CI
// 如果成功 → 提示你检查是否可以移除 expectFailure
}
// 用 async/await 替代 XCTestExpectation
func testAsyncDataLoading() async throws {
let data = try await dataSource.load()
// 不需要设置超时,等待自然完成
// 如果超时了,CI 的全局超时会捕获
XCTAssertFalse(data.isEmpty)
}
// setUp 中生成 mock 数据而非依赖外部状态
override func setUp() {
super.setUp()
// 每次测试前生成干净的数据
let mockMenu = generateMockMenu()
foodTruck = FoodTruck(menu: mockMenu)
}
最佳实践
- 所有测试状态在 setUp 中准备,不依赖 tearDown 清理
- 用环境变量区分 CI 环境,避免在错误环境执行破坏性操作
- 能用 async/await 就不用 XCTestExpectation
- 预期会失败的测试用 XCTExpectFailure 而不是禁用
- 在 Xcode Cloud 的 Workflow 中配置并行测试执行,缩短总耗时
还有什么值得关注
- “Meet Xcode Cloud” 是入门必看
- “Customize your advanced Xcode Cloud workflow” 讲解了 custom build scripts 的用法
- “XCTSkip your tests” 是本 Session 的互补内容
- 建议把测试可靠性指标纳入团队日常关注,CI 失败不应被视为”常态”
WWDC 2022