0

我正在使用 XCTWaiter 等待 UI 自动化设置中的某些条件。这是我的自定义 waitFor 方法:

// UITools.swift
public class func waitFor(_ element:Any, timeout:UInt, clause:String) -> Bool
{
    let predicate = NSPredicate(format: clause)
    let expectation = testcase.expectation(for: predicate, evaluatedWith: element)

    print("Waiting for \(element) to become \"\(clause)\" within \(timeout) seconds ...")

    let result = XCTWaiter.wait(for: [expectation], timeout: TimeInterval(timeout))

    switch result
    {
        case .completed:
            return true
        case .invertedFulfillment:
            print("waitFor result is in inverted fulfillment.")
            return true
        case .timedOut:
            print("waitFor result is timed out.")
        case .incorrectOrder:
            print("waitFor result is in incorrect order.")
        case .interrupted:
            print("waitFor result is interrupted.")
    }

    return false
}

这种方法在我等待 XCUIElements 但我想等待网络请求完成的情况下工作正常,所以我使用一个在网络请求完成后设置为 true 的标志。这是一个简化的示例:

class Hub : NSObject
{
    var isTestRailCasesRetrived = false

    func retrieveTestRailCaseData()
    {
        isTestRailCasesRetrived = false

        testrailClient.getTestCases()
        {
            (response:TestRailModel) in
                // Do processing here ...
                print("Found \(totalCases) TestRail cases for suite with ID \(suite.id).")
                self.isTestRailCasesRetrived = true
        }

        UITools.waitFor(self, timeout: 30, clause: "isTestRailCasesRetrived == true")
    }
}

但是,XCTWaiter 永远不会完成,只是在超时后超时。在这种情况下似乎isTestRailCasesRetrived从未评估过。有人知道为什么吗?

4

2 回答 2

0

找到了解决方法。此方法在上述代码没有的特殊情况下成功运行。它阻止 XCUITest 代码执行,直到这个等待循环完成......

/// Ass-simple brute force wait method for when nothing else works.
///
public class func waitUntil(timeout:Int = 30, evalblock:@escaping (() -> Bool))
{
    var count = 0
    repeat
    {
        if count >= timeout || evalblock() == true
        {
            break
        }
        else
        {
            Darwin.sleep(1)
        }
        count += 1
    }
    while true
}
于 2017-10-27T09:16:20.693 回答
0

NSPredicate 与 Objective-C 运行时一起工作,并且由它评估的属性或函数必须用 @objc 属性标记。

解决方案:

class Hub : NSObject
{
    @objc var isTestRailCasesRetrived = false

    func retrieveTestRailCaseData()
    {
        isTestRailCasesRetrived = false

        testrailClient.getTestCases()
        {
            (response:TestRailModel) in
                // Do processing here ...
                print("Found \(totalCases) TestRail cases for suite with ID \(suite.id).")
                self.isTestRailCasesRetrived = true
        }

        UITools.waitFor(self, timeout: 30, clause: "isTestRailCasesRetrived == true")
    }
}
于 2021-03-01T07:40:55.953 回答