2015-11-12 26 views
6

Ho un banco di prova per una vista collezione che funziona così:cellule errati contare per la vista raccolta in UI Test

func testDeleteItem() { 
    app.collectionViews.staticTexts["Item"].tap() 
    app.buttons["Delete"].tap() 

    XCTAssertEqual(app.collectionViews.cells.count, 2) 
    XCTAssertFalse(app.collectionViews.cells.staticTexts["Item"].exists) 
} 

Dopo il rubinetto, c'è un nuovo schermo con il tasto di cancellazione. Toccando il pulsante, lo schermo si chiude da solo e ricarica la vista raccolta. Tutto funziona come previsto nell'interfaccia utente, ma ottengo entrambi gli insuccessi. Nel primo conteggio è ancora 3 e nel secondo elemento esiste ancora.

Modifica: Ho creato questo simple example on GitHub per presentare il bug.

+0

vedo prova simulatore come va e dovrebbe essere ok. Le schermate mostrano anche 2 elementi rimanenti.Ho pensato che potesse fallire perché non aspetta di finire di licenziare lo schermo, ma 'expectationForPredicate' con' waitForExpectationsWithTimeout' ha esito negativo. –

+0

I registri non mostrano nulla fuori servizio. –

+0

Anche questo test fallisce, quando la cella viene cancellata direttamente su 'collectionView: didSelectCell:', inserendo il vecchio asserito 'dispatch_async' i test passano. Non sembra essere una soluzione adeguata, ma sottolinea anche il threading. Interessante –

risposta

10

Ho trovato la soluzione, ma è una soluzione alternativa per un comportamento API errato. La vista Raccolta è la cella di cache, probabilmente è per questo che ho 3 celle, anche se ne ho rimossa una. cellule eliminato è fuori schermo, in modo da poter verificare se è hittable: estensione

XCTAssertFalse(app.cells.staticTexts["Item"].hittable) 

Per trovare un conteggio, ho creato:

extension XCUIElementQuery { 
    var countForHittables: UInt { 
     return UInt(allElementsBoundByIndex.filter { $0.hittable }.count) 
    } 
} 

e il mio test è simile al seguente:

func testDeleteItem() { 
    app.collectionViews.staticTexts["Item"].tap() 
    app.buttons["Delete"].tap() 

    XCTAssertEqual(app.collectionViews.cells.countForHittables, 2) 
    XCTAssertFalse(app.collectionViews.cells.staticTexts["Item"].hittable) 
} 
+0

Ho appena avuto questo problema. La necessità di una soluzione è sfortunata, ma la soluzione funziona, che è grande. Grazie! – greymouser

1

Mi sono imbattuto in questo problema, ma nel mio caso, la query .cells non è stata valutata correttamente. Invece di .cells, utilizzando

XCUIApplication().collectionViews.element.childrenMatchingType(.Cell).count 

ha funzionato per me e restituito il conteggio corretto.


Aggiornamento:

ho anche scoperto che scorrendo la vista in modo che tutte le cellule sono rimosse dalla coda prima di ottenere il conteggio risolto il problema. Sembra che il framework di accessibilità non trovi le altre celle fino a quando non sono state rimosse dalla coda (immagino che abbia senso).

XCUIApplication().collectionViews.element.swipeUp()

0

mi sono imbattuto in questa domanda, quando stavo cercando la stessa risposta, ma in Objective-C. Per chi, come me, mi sono adattato @ il metodo di Tomasz contare collezione guarda le cellule nei test dell'interfaccia utente:

-(NSInteger)countForHittables:(NSArray<XCUIElement*>*)collectionView{ 
    __block int hittables = 0; 
    [collectionView enumerateObjectsUsingBlock:^(XCUIElement * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 
     if (obj.hittable){ 
      hittables++; 
     } 
    }]; 
    return hittables; 
} 

chiamarlo: [self countForHittables:app.collectionViews.cells.allElementsBoundByIndex];.

0

Ho avuto lo stesso problema. Anche se la raccolta non è stata compilata perché era in attesa della risposta di un'API, cells.count> = 1 era sempre true.

Quello che ho fatto, sulla base di Tomasz Bąk's answer ho creato un'estensione di aspettare per la raccolta a essere popolato:

extension XCTestCase { 
    func waitForCollectionToBePopulated(_ element: XCUIElement, timeout: TimeInterval) { 
     let query = element.cells 
     let p = NSPredicate(format: "countForHittables >= 1") 
     let e = expectation(for: p, evaluatedWith: query, handler: nil) 
     wait(for: [e], timeout: timeout) 
    } 
} 

E sul sito chiamante avrà un aspetto:

waitForCollectionToBePopulated(collection, timeout: {timeOut})