ios - विलंब/Xcode UI परीक्षण के परीक्षण मामले में प्रतीक्षा करें




ios9 xcode-ui-testing (7)

XCUIElement के लिए एपीआई के अनुसार .exists का उपयोग यह जांचने के लिए किया जा सकता है कि क्या कोई क्वेरी मौजूद है या नहीं, इसलिए निम्न सिंटैक्स कुछ मामलों में उपयोगी हो सकता है!

let app = XCUIApplication()
app.launch()

let label = app.staticTexts["Hello, world!"]
while !label.exists {
    sleep(1)
}

यदि आप आश्वस्त हैं कि आपकी अपेक्षा पूरी हो जाएगी तो आप इसे चलाने का प्रयास कर सकते हैं। यह ध्यान दिया जाना चाहिए कि यदि प्रतीक्षा बहुत लंबी है तो दुर्घटनाग्रस्त होना बेहतर हो सकता है, अगर @Joe Masilotti की पोस्ट से waitForExpectationsWithTimeout(_,handler:_) का उपयोग किया जाए।

मैं Xcode 7 बीटा 2 में उपलब्ध नए UI परीक्षण का उपयोग करके एक परीक्षण मामले को लिखने की कोशिश कर रहा हूं। ऐप में एक लॉगिन स्क्रीन है जहां यह सर्वर पर लॉगिन करने के लिए कॉल करता है। इससे जुड़ा एक विलंब है क्योंकि यह एक अतुल्यकालिक ऑपरेशन है।

क्या आगे कदम बढ़ाने से पहले XCTestCase में देरी या प्रतीक्षा तंत्र का कारण है?

कोई उचित दस्तावेज उपलब्ध नहीं है और मैं कक्षाओं की हैडर फाइलों के माध्यम से चला गया। इससे संबंधित कुछ भी खोजने में सक्षम नहीं था।

कोई विचार / सुझाव?


Xcode 8.3 के रूप में, हम XCTWaiter http://masilotti.com/xctest-waiting/ उपयोग कर सकते हैं

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
}

एक और ट्रिक है वेट फंक्शन लिखने की, इसका श्रेय मुझे दिखाने के लिए जॉन सुंडेल को जाता है

extension XCTestCase {

  func wait(for duration: TimeInterval) {
    let waitExpectation = expectation(description: "Waiting")

    let when = DispatchTime.now() + duration
    DispatchQueue.main.asyncAfter(deadline: when) {
      waitExpectation.fulfill()
    }

    // We use a buffer here to avoid flakiness with Timer on CI
    waitForExpectations(timeout: duration + 0.5)
  }
}

और इसका उपयोग करें

func testOpenLink() {
  let delegate = UIApplication.shared.delegate as! AppDelegate
  let route = RouteMock()
  UIApplication.shared.open(linkUrl, options: [:], completionHandler: nil)

  wait(for: 1)

  XCTAssertNotNil(route.location)
}

इसके अतिरिक्त, आप बस सो सकते हैं:

sleep(10)

चूंकि UITests एक अन्य प्रक्रिया में चलती है, इसलिए यह काम करता है। मुझे नहीं पता कि यह कितना उचित है, लेकिन यह काम करता है।


निम्नलिखित कोड सिर्फ उद्देश्य सी के साथ काम करता है।

- (void)wait:(NSUInteger)interval {

    XCTestExpectation *expectation = [self expectationWithDescription:@"wait"];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [expectation fulfill];
    });
    [self waitForExpectationsWithTimeout:interval handler:nil];
}

बस नीचे दिए गए अनुसार इस फ़ंक्शन को कॉल करें।

[self wait: 10];

Xcode 9 ने XCTWaiter साथ नई चालें पेश XCTWaiter

टेस्ट केस स्पष्ट रूप से प्रतीक्षा करता है

wait(for: [documentExpectation], timeout: 10)

वेटर उदाहरण परीक्षण करने के लिए प्रतिनिधियों

XCTWaiter(delegate: self).wait(for: [documentExpectation], timeout: 10)

वेटर वर्ग के परिणाम

let result = XCTWaiter.wait(for: [documentExpectation], timeout: 10)
switch(result) {
case .completed:
    //all expectations were fulfilled before timeout!
case .timedOut:
    //timed out before all of its expectations were fulfilled
case .incorrectOrder:
    //expectations were not fulfilled in the required order
case .invertedFulfillment:
    //an inverted expectation was fulfilled
case .interrupted:
    //waiter was interrupted before completed or timedOut
}

नमूना उपयोग

Xcode 9 से पहले

उद्देश्य सी

- (void)waitForElementToAppear:(XCUIElement *)element withTimeout:(NSTimeInterval)timeout
{
    NSUInteger line = __LINE__;
    NSString *file = [NSString stringWithUTF8String:__FILE__];
    NSPredicate *existsPredicate = [NSPredicate predicateWithFormat:@"exists == true"];

    [self expectationForPredicate:existsPredicate evaluatedWithObject:element handler:nil];

    [self waitForExpectationsWithTimeout:timeout handler:^(NSError * _Nullable error) {
        if (error != nil) {
            NSString *message = [NSString stringWithFormat:@"Failed to find %@ after %f seconds",element,timeout];
            [self recordFailureWithDescription:message inFile:file atLine:line expected:YES];
        }
    }];
}

उपयोग

XCUIElement *element = app.staticTexts["Name of your element"];
[self waitForElementToAppear:element withTimeout:5];

तीव्र

func waitForElementToAppear(element: XCUIElement, timeout: NSTimeInterval = 5,  file: String = #file, line: UInt = #line) {
        let existsPredicate = NSPredicate(format: "exists == true")

        expectationForPredicate(existsPredicate,
                evaluatedWithObject: element, handler: nil)

        waitForExpectationsWithTimeout(timeout) { (error) -> Void in
            if (error != nil) {
                let message = "Failed to find \(element) after \(timeout) seconds."
                self.recordFailureWithDescription(message, inFile: file, atLine: line, expected: true)
            }
        }
    }

उपयोग

let element = app.staticTexts["Name of your element"]
self.waitForElementToAppear(element)

या

let element = app.staticTexts["Name of your element"]
self.waitForElementToAppear(element, timeout: 10)

SOURCE


iOS 11 / Xcode 9

<#yourElement#>.waitForExistence(timeout: 5)

यह इस साइट पर सभी कस्टम कार्यान्वयन के लिए एक महान प्रतिस्थापन है!

मेरे जवाब पर एक नज़र ज़रूर डालें: https://.com/a/48937714/971329 वहाँ मैं अनुरोधों के लिए प्रतीक्षा करने के लिए एक विकल्प का वर्णन करता हूं जो आपके परीक्षणों के चलने के समय को बहुत कम कर देगा!


share आधार पर, मैंने इस एक्सटेंशन का उपयोग किया है:

extension XCTestCase {

    // Based on https://.com/a/33855219
    func waitFor<T>(object: T, timeout: TimeInterval = 5, file: String = #file, line: UInt = #line, expectationPredicate: @escaping (T) -> Bool) {
        let predicate = NSPredicate { obj, _ in
            expectationPredicate(obj as! T)
        }
        expectation(for: predicate, evaluatedWith: object, handler: nil)

        waitForExpectations(timeout: timeout) { error in
            if (error != nil) {
                let message = "Failed to fulful expectation block for \(object) after \(timeout) seconds."
                self.recordFailure(withDescription: message, inFile: file, atLine: line, expected: true)
            }
        }
    }

}

आप इसे इस तरह से उपयोग कर सकते हैं

let element = app.staticTexts["Name of your element"]
waitFor(object: element) { $0.exists }

यह किसी तत्व के गायब होने की प्रतीक्षा करने, या किसी अन्य संपत्ति को बदलने की अनुमति देता है (उपयुक्त ब्लॉक का उपयोग करके)

waitFor(object: element) { !$0.exists } // Wait for it to disappear






xctwaiter