Swift中如何通过循环对异步函数进行压力测试?测试代码遇阻求助
异步用户创建接口异常场景测试修复方案
问题核心诊断
你的测试代码存在几个关键问题,导致无法正常完成所有异常场景的验证:
- 仅使用单个预期对象(expectation),循环中多次调用
exp.fulfill()会让测试在第一个异步回调完成后就提前结束,后续场景根本不会被验证 - 用
sleep(5)阻塞线程等待异步操作,这是低效且不可靠的方式,无法保证异步请求真的完成 - 测试数据中的
properEmail、properPassword等变量为空字符串,没有设置实际合法值,导致场景逻辑不成立 - 循环中并发发起异步请求,可能引发竞态条件,导致测试结果不稳定
修复后的测试代码
func test_Repository_UserCreationErrorScenarios() { // 配置符合业务规则的合法邮箱和密码 let properEmail = "valid@example.com" let properPassword = "ValidPass123!" let improperEmail = "invalid-email-format" let improperPassword = "short" // 不符合密码复杂度要求 // 定义所有异常测试场景,附带场景描述便于定位问题 let testScenarios: [(email: String, password: String, description: String)] = [ ("", "", "邮箱和密码均为空"), ("", properPassword, "空邮箱"), (properEmail, "", "空密码"), (improperEmail, properPassword, "无效格式邮箱"), (properEmail, improperPassword, "无效格式密码") ] let repo = UserRepository() // 为每个测试场景创建独立的预期对象 let expectations = testScenarios.map { scenario in expectation(description: "验证场景:\(scenario.description)") } for (index, scenario) in testScenarios.enumerated() { repo.createNewUser(scenario.email, password: scenario.password) { [weak self] _, error in guard let self = self else { return } // 断言当前场景必须返回错误 XCTAssertNotNil(error, "场景[\(scenario.description)]未返回预期错误") // 标记对应场景的预期对象完成 expectations[index].fulfill() } } // 等待所有异步场景完成,超时时间根据实际需求调整 wait(for: expectations, timeout: 30.0) }
关键修复点说明
- 每个场景对应独立的Expectation:避免单个预期对象被提前触发,确保所有异常场景都能完成验证
- 移除sleep阻塞:改用XCTest原生的
wait(for:timeout:)机制,正确等待所有异步操作完成 - 填充合法测试数据:设置实际有效的邮箱和密码,保证测试场景的逻辑正确性
- 场景关联验证:通过索引关联场景与对应的预期对象,确保每个回调都对应到正确的测试场景
- 添加场景描述:在预期对象和断言中加入场景说明,方便快速定位失败的测试用例
额外优化建议
- 可以细化错误验证:针对不同场景断言对应的错误码或错误信息,而不仅仅是断言错误非空
- 如果使用Firebase Auth,建议在测试前初始化独立的测试环境,避免影响生产数据
- 考虑使用测试替身(Test Double)模拟
auth.createUser的行为,让测试不依赖真实网络服务,提升测试速度和稳定性
内容的提问来源于stack exchange,提问作者ibrahim erdogan
相关产品推荐
相关产品推荐

