2015-11-12 3 views
6

Tests ich einen Test für eine Sammlung Ansicht, die wie folgt funktioniert:Wrong Zellen zählen in UI Sammlung Ansicht

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

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

Nach dem Wasserhahn, ein neuer Bildschirm mit der Löschtaste ist. Wenn die Schaltfläche angetippt wird, wird der Bildschirm automatisch beendet und die Sammlungsansicht erneut geladen. Alles geht wie erwartet in der Benutzeroberfläche, aber ich bekomme beide Behauptungen fehlgeschlagen. In der ersten Zählung ist es immer noch 3 und in der zweiten zählt es noch.

Bearbeiten: Ich habe dieses simple example on GitHub erstellt, um den Fehler zu präsentieren.

+0

I-Test in Simulator sehen wie es geht und es sollte ok sein. Screenshots zeigen auch 2 Artikel übrig.Ich dachte, es kann scheitern, weil es nicht darauf wartet, die Bildschirmabweisung zu beenden, aber "expectationForPredicate" mit "waitForExpectationsWithTimeout" schlägt ebenfalls fehl. –

+0

Logs zeigen nichts außer Betrieb. –

+0

Dieser Test schlägt auch fehl, wenn die Zelle direkt in 'collectionView: didSelectCell:' gelöscht wird, wodurch die Tests in altem guten 'dispatch_async' ausgeführt werden. Es scheint keine richtige Lösung zu sein, weist aber auch auf Threading hin. Interessant –

Antwort

10

Ich habe die Lösung gefunden, aber es ist ein Workaround für falsches API-Verhalten. In der Sammelansicht werden Zellen zwischengespeichert. Das ist wahrscheinlich der Grund, warum ich 3 Zellen habe, auch wenn ich eine Zelle entfernt habe. Gelöschte Zelle ist außerhalb des Bildschirms, Sie können so testen, ob es hittable ist:

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

Um eine Zählung zu finden, habe ich erstellt Erweiterung:

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

und mein Test sieht wie folgt aus:

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

Gerade hatte dieses Problem auch. Die Notwendigkeit einer Problemumgehung ist bedauerlich, aber die Problemumgehung funktioniert, was großartig ist. Vielen Dank! – greymouser

1

Ich stieß auch auf dieses Problem, aber in meinem Fall wurde die .cells-Abfrage nicht richtig ausgewertet. Anstelle von .Zellen

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

arbeitete für mich und gab die korrekte Zählung zurück.


aktualisieren:

Ich fand auch, dass die Ansicht scrollen, so dass alle Zellen die Zählung, bevor sie das Problem behoben aus der Warteschlange entfernt werden. Es scheint so, als würde das Framework für Barrierefreiheit die anderen Zellen erst finden, wenn sie aus der Warteschlange entfernt wurden (ich denke, das macht Sinn).

XCUIApplication().collectionViews.element.swipeUp()

0

ich in diese Frage lief, als ich für die gleiche Antwort suchen, aber in Objective-C. Für diejenigen, die wie ich angepasst I @ Methode Tomasz Sammlung Ansicht Zellen in UI-Tests zu zählen:

-(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; 
} 

es zu nennen: [self countForHittables:app.collectionViews.cells.allElementsBoundByIndex];.

0

Ich hatte das gleiche Problem. Selbst wenn die Sammlung nicht gefüllt wurde, weil sie auf die Antwort einer API gewartet hat, war cells.count> = 1 immer wahr.

Was habe ich, basierend auf Tomasz Bąk's answer habe ich eine Erweiterung zu warten, bis die Sammlung gefüllt werden:

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) 
    } 
} 

Und auf der Anrufer-Website aussehen wird:

waitForCollectionToBePopulated(collection, timeout: {timeOut})