UI 测试中集合视图的错误单元格计数
Posted
技术标签:
【中文标题】UI 测试中集合视图的错误单元格计数【英文标题】:Wrong cells count for collection view in UI Tests 【发布时间】:2015-11-12 19:36:03 【问题描述】:我有一个像这样工作的集合视图的测试:
func testDeleteItem()
app.collectionViews.staticTexts["Item"].tap()
app.buttons["Delete"].tap()
XCTAssertEqual(app.collectionViews.cells.count, 2)
XCTAssertFalse(app.collectionViews.cells.staticTexts["Item"].exists)
点击后,会出现一个带有删除按钮的新屏幕。点击按钮时,屏幕会自行关闭并重新加载集合视图。 UI 中的一切都按预期进行,但我的两个断言都失败了。在第一个计数中它仍然是 3,在第二个项目中它仍然存在。
【问题讨论】:
我在模拟器中看到了测试,它应该没问题。屏幕截图还显示还剩下 2 个项目。我认为它可能会失败,因为它不会等待完成屏幕关闭,但expectationForPredicate
和 waitForExpectationsWithTimeout
也会失败。
日志没有显示任何乱序。
这个测试也失败了,当直接在collectionView:didSelectCell:
上删除单元格时,将断言放入旧好的dispatch_async
使测试通过。它似乎不是一个合适的解决方案,但也指出了线程。有趣
我无法通过dispatch_async
,您是如何做到的?
我用dispatch_async(dispatch_get_main_queue())
包装了断言,无论如何dispatch_async
是不行的,它只会导致断言不被考虑XCTAssertFalse(true)
也通过了;)你试过了吗?相同的场景,但使用 tableView?如果这可行,则可能表明确实存在一些错误
【参考方案1】:
我找到了解决方案,但它是错误 API 行为的解决方法。集合视图正在缓存单元格,这可能就是我有 3 个单元格的原因,即使我已经删除了一个。删除的单元格不在屏幕上,所以你可以测试它是否是hittable
:
XCTAssertFalse(app.cells.staticTexts["Item"].hittable)
为了找到一个计数,我创建了扩展:
extension XCUIElementQuery
var countForHittables: UInt
return UInt(allElementsBoundByIndex.filter $0.hittable .count)
我的测试看起来像这样:
func testDeleteItem()
app.collectionViews.staticTexts["Item"].tap()
app.buttons["Delete"].tap()
XCTAssertEqual(app.collectionViews.cells.countForHittables, 2)
XCTAssertFalse(app.collectionViews.cells.staticTexts["Item"].hittable)
【讨论】:
刚刚也遇到了这个问题。不幸的是,需要解决方法,但解决方法有效,这很棒。谢谢!【参考方案2】:我也遇到了这个问题,但就我而言,.cells 查询没有正确评估。而不是 .cells,使用
XCUIApplication().collectionViews.element.childrenMatchingType(.Cell).count
为我工作并返回正确的计数。
更新:
我还发现滚动视图以使所有单元格在获得计数之前出列,从而解决了问题。似乎可访问性框架在它们被出列之前不会找到其他单元格(我想这是有道理的)。
XCUIApplication().collectionViews.element.swipeUp()
【讨论】:
【参考方案3】:我认为单元格查询返回当前视图层次结构中所有表中的所有单元格。尝试这样做app.tables.firstMatch.cells.count
,它对我有用。
【讨论】:
【参考方案4】:我在寻找相同答案时遇到了这个问题,但在 Objective-C 中。对于像我这样的人,我采用了@Tomasz 的方法来计算 UI 测试中的 Collection View 单元格:
-(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;
调用它:[self countForHittables:app.collectionViews.cells.allElementsBoundByIndex];
。
【讨论】:
【参考方案5】:我遇到了同样的问题。即使由于等待 API 响应而没有填充集合,cells.count >= 1 也始终为真。
我做了什么,基于Tomasz Bąk's answer 我创建了一个扩展来等待集合被填充:
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)
并且在调用者网站上会看到:
waitForCollectionToBePopulated(collection, timeout: timeOut)
【讨论】:
以上是关于UI 测试中集合视图的错误单元格计数的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Swift 在 XCode UI 自动化中选择随机表格视图单元格