2015-12-02 10 views
9

Voglio una pausa di prova e attendere che un elemento appaia sullo schermo prima di procedere.Test dell'interfaccia utente Swift2 - Attendi che l'elemento venga visualizzato

non vedo un buon modo per creare un'aspettativa per questo e aspetto con

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

Il metodo per creare un'aspettativa ho utilizzato è stato

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

Ma questo richiede un elemento già esistente, mentre mi piacerebbe che il test attenda un elemento che non esiste ancora.

Qualcuno conosce il modo migliore per farlo?

risposta

15

In expectationForPredicate(predicate: evaluatedWithObject: handler:) non si fornisce un oggetto reale, ma una query per trovarlo nella gerarchia della vista. Così, per esempio, questo è un test valido:

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

waitForExpectationsWithTimeout(3, handler: nil) 

Partenza UI Testing Cheat Sheet e documentation generato dalle intestazioni (non v'è alcuna documentazione ufficiale al momento), tutti di Joe Masilotti.

+1

Grazie per l'urlo! –

+0

Avrei potuto giurare di averlo provato in una versione precedente dei test dell'interfaccia utente e non ha funzionato, vabbè, grazie – Alex

+0

Anche questo helper aiuta http://masilotti.com/xctest-helpers/ – onmyway133

1

Non richiede un elemento già esistente. Hai solo bisogno di definire il seguente predicato:

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

poi basta usare questo predicato nella vostra aspettativa. Quindi, naturalmente, aspetta le tue aspettative.

+0

Ho un esempio in Objective-C, non in fretta. Posso includerlo se ne hai bisogno. – sylvanaar

+0

Questa è una risposta corretta, grazie! – Alex

3

È possibile utilizzare questo, a 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, è possibile utilizzare la nuova API waitForExistence

0

Per Xcode 8.3 e successivamente si può aspettare che le aspettative con un nuovo classe - XCTWaiter, un test di esempio si presenta:

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 per ulteriori informazioni.

0

Sulla base di onmyway133 code mi è venuta a estensioni (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] 
    } 
} 

Quindi, sul tuo sito chiamata, è possibile utilizzare:

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