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

时间:2016-08-04 18:15:42

标签: asynchronous xctest xcode-ui-testing

我为与服务器通信的应用程序进行测试自动化。该应用程序有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 个答案:

答案 0 :(得分:1)

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

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

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