在 UI 测试 Swift 中处理来自 API 的答案

Posted

技术标签:

【中文标题】在 UI 测试 Swift 中处理来自 API 的答案【英文标题】:Handling the answer from API in UI Testing Swift 【发布时间】:2021-10-07 16:32:14 【问题描述】:

我有天气应用程序。它从 API 获取数据。我输入所需的城市,然后下一个屏幕打开并显示城市名称和温度。我正在编写 UI 测试,它应该打开应用程序,处理要求使用位置的警报,然后测试应该写下城市名称并检查屏幕中是否存在这个城市。除了最后检查城市名称之外的所有工作。我想问题可能是因为它需要一些时间才能从 API 中获得答案,而测试不会等待它。也许我需要设置计时器来等待答案。还是问题出在其他地方? 这是我的代码,它在最后一行失败了。

    func testExample() throws 
        
        let app = XCUIApplication()
        app.launchArguments = ["enable-testing"]
        app.launch()
        
        app/*@START_MENU_TOKEN@*/.staticTexts["My location"]/*[[".buttons[\"My location\"].staticTexts[\"My location\"]",".staticTexts[\"My location\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.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 // The alert was handled
            

            return false // The alert was not handled
        
        
        app.textFields["Enter your city"].tap()
        app.textFields["Enter your city"].typeText("Barcelona")
        
        app.buttons["Check weather"].tap()
        
        XCTAssertTrue(app.staticTexts["Barcelona"].exists)
       
    

【问题讨论】:

嗯,其实有两个问题。一个是,是的,这是一个异步操作,所以你必须使用异步测试。另一个是你真的不应该在测试中涉及真正的互联网。 @matt hm 互联网很有趣,我是这个领域的新手,所以谢谢,我会尝试找到更多信息 您可能想查看 API 模拟。如果 API 不可用或数据发生更改,使用模拟将避免您的测试失败。它们还将允许您测试错误处理。在测试之外,如果当时 API 出现任何问题,它们对于开发也很有用 ***.com/search?q=%5Bios%5D+stub+http+unit+test 【参考方案1】:

XCTest 自带一个你需要的内置函数

文档:https://developer.apple.com/documentation/xctest/xcuielement/2879412-waitforexistence/

示例: XCTAssertTrue(myButton.waitForExistence(timeout: 3), "Button did not appear")

【讨论】:

【参考方案2】:

我找到了这个函数并用它来等待结果。 这是我的代码中的函数及其用法。

    func waitForElementToAppear(_ element: XCUIElement) -> Bool 
        let predicate = NSPredicate(format: "exists == true")
        let expectation = expectation(for: predicate, evaluatedWith: element,
                                      handler: nil)
        let result = XCTWaiter().wait(for: [expectation], timeout: 5)
        return result == .completed
    


        app.textFields["Enter your city"].tap()
        app.textFields["Enter your city"].typeText("Barcelona")
        app.buttons["Check weather"].tap()
        let result = app.staticTexts["Barcelona"]
        waitForElementToAppear(result)

        XCTAssertTrue(result.exists)

【讨论】:

以上是关于在 UI 测试 Swift 中处理来自 API 的答案的主要内容,如果未能解决你的问题,请参考以下文章

XCode UI 测试 swizzle API 类方法

如何在 Swift UI 中删除 Picker 视图的灰色背景框

如何在 Swift 中编写 UI 测试,以测试点击按钮时标签是不是可见?

Android视频编辑SDK--RDVECore来自锐动的无UI,高度抽象化API

RDVECore来自锐动的无UI,高度抽象化API的视频编辑SDK--IOS版

在 Swift 中解码 JSON API - 重复的结构名称