XCTWaiter Ожидание не стреляет

Я использую XCTWaiter для ожидания определенных условий в настройке автоматизации пользовательского интерфейса. Это мой пользовательский метод 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 никогда не оценивается в этой ситуации. Кто-нибудь знает почему?

2 ответа

Нашел обходной путь. Этот метод успешно работает в данном конкретном случае, где приведенный выше код не работает. Он блокирует выполнение кода 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
}

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")
    }
}
Другие вопросы по тегам