2015-12-02 7 views
9

Ich möchte eine Testpause haben und warten, bis ein Element auf dem Bildschirm erscheint, bevor ich fortfahre.Swift2 UI Test - Warte auf das Erscheinen des Elements

Ich sehe nicht ein guter Weg, eine Erwartung für diese erstellen und warten eine Erwartung mit

public func waitForExpectationsWithTimeout(timeout: NSTimeInterval, handler: XCWaitCompletionHandler?) 

Verfahren erstellen Ich habe

public func expectationForPredicate(predicate: NSPredicate, evaluatedWithObject object: AnyObject, handler: XCPredicateExpectationHandler?) -> XCTestExpectation 

wurde unter Verwendung Aber das dauert ein bereits vorhandenes Element, während ich möchte, dass der Test auf ein Element wartet, das noch nicht existiert.

Kennt jemand den besten Weg, dies zu tun?

Antwort

15

In expectationForPredicate(predicate: evaluatedWithObject: handler:) geben Sie kein tatsächliches Objekt, sondern eine Abfrage, um es in der Ansichtshierarchie zu finden. So zum Beispiel, das ist ein gültiger Test:

let predicate = NSPredicate(format: "exists == 1") 
let query = XCUIApplication().buttons["Button"] 
expectationForPredicate(predicate, evaluatedWithObject: query, handler: nil) 

waitForExpectationsWithTimeout(3, handler: nil) 

Check out UI Testing Cheat Sheet und documentation aus den Header erzeugt (es gibt keine offizielle Dokumentation zur Zeit), die alle von Joe Masilotti.

+1

Danke für den Ruf raus! –

+0

Ich hätte schwören können, dass ich dies in einer früheren Version der UI-Tests ausprobiert habe und es nicht funktioniert hat, na ja, danke – Alex

+0

Auch dieser Helfer hilft http://masilotti.com/xctest-helpers/ – onmyway133

1

Es braucht kein bereits vorhandenes Element. Sie müssen nur die folgende Prädikat definieren:

let exists = NSPredicate(format: "exists = 1")

Dann nutzen Sie einfach dieses Prädikat in Ihrer Erwartung. Dann warte natürlich auf deine Erwartung.

+0

Ich habe ein Beispiel, in Objective-C, nicht in schnell. Ich kann es einschließen, wenn Sie es brauchen. – sylvanaar

+0

Dies ist eine korrekte Antwort, danke! – Alex

3

können Sie diese verwenden, in Swift 3

func wait(element: XCUIElement, duration: TimeInterval) { 
    let predicate = NSPredicate(format: "exists == true") 
    let _ = expectation(for: predicate, evaluatedWith: element, handler: nil) 

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

In Xcode 9, iOS 11, können Sie die neue API waitForExistence

0

Für Xcode 8.3 und später können Sie für Erwartung mit einem neuen warten verwenden Klasse - XCTWaiter, sieht ein Beispiel Test wie folgt aus:

func testExample() { 
    let element = // ... 
    let predicate = NSPredicate(format: "exists == true") 
    let expectation = XCTNSPredicateExpectation(predicate: predicate, object: element) 

    let result = XCTWaiter().wait(for: [expectation], timeout: 1) 
    XCTAssertEqual(.completed, result) 
} 

Read the documentation für weitere Informationen.

0

Basierend auf onmyway133 code kam ich mit auf Erweiterungen (Swift 3.2):

extension XCTestCase { 
    func wait(for element: XCUIElement, timeout: TimeInterval) { 
    let p = NSPredicate(format: "exists == true") 
    let e = expectation(for: p, evaluatedWith: element, handler: nil) 
    wait(for: [e], timeout: timeout) 
    } 
} 

extension XCUIApplication { 
    func getElement(withIdentifier identifier: String) -> XCUIElement { 
    return otherElements[identifier] 
    } 
} 

So auf Ihren Anruf-Website können Sie:

wait(for: app.getElement(withIdentifier: "ViewController"), timeout: 10)