XCTest:如何检查异步元素是不是存在

Posted

技术标签:

【中文标题】XCTest:如何检查异步元素是不是存在【英文标题】:XCTest: how to check whether an asynchronous element existsXCTest:如何检查异步元素是否存在 【发布时间】:2016-08-04 18:15:42 【问题描述】:

我致力于与服务器通信的应用程序的测试自动化。该应用程序有 7 个预定义的字符串。根据服务器返回的信息,这不是确定性的并且取决于外部因素,应用程序将七个预定义字符串中的一到三个作为可点击的静态文本放置在表格视图中。用户可以选择要点击哪些字符串。 为了自动化这个测试,我需要一种异步方式来确定测试代码中 7 个预定义字符串中的哪个实际出现在屏幕上。 我不能使用 element.exists 因为静态文本出现需要时间,我不想调用 sleep() 因为这会减慢测试速度。 所以我尝试使用 XCTestExpectation 但遇到了问题。当 waitForExpectationsWithTimeout() 超时时,XCTest 总是失败。 为了说明问题,我写了一个简单的测试程序:

func testExample() 
    let element = XCUIApplication().staticTexts["Email"]
    let gotText = haveElement(element)
    print("Got text: \(gotText)")


func haveElement(element: XCUIElement) -> Bool
    var elementExists = true
    let expectation = self.expectationForPredicate(
        NSPredicate(format: "exists == true"),
        evaluatedWithObject: element,
        handler: nil)
    self.waitForExpectationsWithTimeout(NSTimeInterval(5))   error in
        elementExists = error == nil
    
    return elementExists

测试总是失败

Assertion Failure: Asynchronous wait failed: Exceeded timeout of 5 seconds, with unfulfilled expectations: "Expect predicate `exists == 1` for object "Email" StaticText".

我也试过了

func haveElement(element: XCUIElement) -> Bool 
    var elementExists = false
    let actionExpectation = self.expectationWithDescription("Expected element")
    dispatch_async(dispatch_get_main_queue()) 
        while true 
            if element.exists 
                actionExpectation.fulfill()
                elementExists = true
                break
             else 
                sleep(1)
            
        
    
    self.waitForExpectationsWithTimeout(NSTimeInterval(5))   error in
        elementExists = error == nil
        
    return elementExists

在这种情况下,测试总是失败

Stall on main thread.

错误。 所以问题是我如何检查是否存在异步 UI 元素,该元素可能会在指定时间内出现也可能不会出现,而不会在超时时测试失败?

谢谢。

【问题讨论】:

【参考方案1】:

您使测试过于复杂。如果您正在与服务器通信,则测试中存在不必要的可变性——我的建议是针对每种情况使用存根网络数据。

您可以在此处获得对存根网络数据的简要介绍: http://masilotti.com/ui-testing-stub-network-data/

您将根据服务器的响应时间以及出现哪个字符串的随机性来消除测试中的随机性。创建响应每个案例的测试用例(即,当您点击每个单独的字符串时应用如何响应)

【讨论】:

抱歉,刺伤在我的情况下不起作用,因为应用程序中存在错误,这些错误不仅体现在这 7 个字符串的某些排列下,而且还体现在之前和之后所做的选择。排列的总数太大,无法为每个排列创建测试用例。 真正的问题是为什么 waitForExpectationsWithTimeout 会在期望超时时抛出。有没有办法防止这种情况并让测试代码以 XCTAssert 以外的方式处理超时?在某些情况下,服务器超时意味着对具有不同参数的服务器的重复请求是有序的,而不是仅仅中止该案例。我无法设置 continueAfterFailure = true 因为在大多数其他情况下测试应该在 XCTAssert 失败。

以上是关于XCTest:如何检查异步元素是不是存在的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Cypress.io 检查元素是不是存在

在 JavaScript 中如何检查 html 元素是不是存在?

如何使用jq检查数组中是不是存在元素

单元测试不了解 XCTest 期望的异步 UI 代码?

如何检查附加元素是不是已存在? [复制]

如何检查 Firebase Firestore 的数组中是不是存在元素?