You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift UI测试中API返回结果等待及城市名称校验失败问题排查

问题原因及解决方案

核心问题

断言失败确实是异步等待逻辑缺失导致的:XCUI测试执行是同步的,点击Check weather按钮后会立刻执行下一行断言,不会等待API请求完成、页面渲染完成,此时城市名称的文本还没出现在UI层级里,自然会断言失败。
不要用固定时长的定时器(比如sleep()),这种方案兼容性极差,网络波动时要么超时要么浪费测试时间,苹果官方提供了XCTestExpectation专门处理异步等待场景。

修正后的代码

func testExample() throws {
    let app = XCUIApplication()
    app.launchArguments = ["enable-testing"]
    app.launch()
    
    app.staticTexts["My location"].tap()
    addUIInterruptionMonitor(withDescription: "Allow “APP” to access your location?") { (alert) -> Bool in
        let button = alert.buttons["Only While Using the App"]
        if button.exists {
            button.tap()
            return true
        }
        return false
    }
    // 加完中断监视器后调用一次app.tap()触发系统检测弹窗,避免部分场景下监视器不生效
    app.tap()
    
    app.textFields["Enter your city"].tap()
    app.textFields["Enter your city"].typeText("Barcelona")
    
    app.buttons["Check weather"].tap()
    
    // 新增异步等待逻辑:等待Barcelona文本出现,最多等5秒,时长可根据实际情况调整
    let cityLabel = app.staticTexts["Barcelona"]
    let existsPredicate = NSPredicate(format: "exists == true")
    expectation(for: existsPredicate, evaluatedWith: cityLabel, handler: nil)
    waitForExpectations(timeout: 5, error: "等待城市名称加载超时,API请求可能失败或UI渲染逻辑存在问题")
    
    // 等待通过后再执行断言
    XCTAssertTrue(cityLabel.exists)
}

额外优化建议

  • 如果要提升UI测试稳定性,建议在测试模式下走本地Mock接口返回固定数据,避免真实网络波动、API服务异常导致的测试用例偶现失败
  • 可以给结果页的城市名称Label设置固定的accessibilityIdentifier,不要用文本内容作为定位依据,避免多语言场景下测试失效

内容的提问来源于stack exchange,提问作者julia117

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 12:39:04