Wrong cells count for collection view in UI Tests

北城以北 提交于 2019-12-04 05:57:38

I have found the solution, but it's a workaround for wrong API behavior. Collection view is caching cells, that's probably why I have 3 cells, even if I have removed one. Deleted cell is offscreen, so you can test if it is hittable:

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

To find a count, I have created extension:

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

and my test looks like this:

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

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

I also came across this issue, but in my case, .cells query wasn't evaluating correctly. Instead of .cells, using

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

worked for me and returned the correct count.


Update:

I also found that scrolling the view so that all the cells are dequeued before getting the count fixed the issue. It seems the accessibility framework does not find the other cells until they have been dequeued (I guess that makes sense).

XCUIApplication().collectionViews.element.swipeUp()

I ran into this question when I was looking for the same answer, but in Objective-C. For those like me, I adapted @Tomasz's method to count Collection View cells in UI tests:

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

To call it: [self countForHittables:app.collectionViews.cells.allElementsBoundByIndex];.

I had the same issue. Even if the collection hasn't been populated because it was waiting for the response of an API, cells.count >= 1 was always true.

What I did, based on Tomasz Bąk's answer I created an extension to wait for the collection to be populated:

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

And on the caller site will look:

waitForCollectionToBePopulated(collection, timeout: {timeOut})
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!