Xcode 7 ui 自动化 - 通过 tableview/collectionview 循环
Posted
技术标签:
【中文标题】Xcode 7 ui 自动化 - 通过 tableview/collectionview 循环【英文标题】:Xcode 7 ui automation - loop through a tableview/collectionview 【发布时间】:2015-11-09 15:25:53 【问题描述】:我正在使用 xCode 7.1。我想自动与表格/集合视图中的所有单元格交互。我希望它是这样的:
for i in 0..<tableView.cells.count
let cell = collectionView.cells.elementBoundByIndex(i)
cell.tap()
backBtn.tap()
然而,这个 sn-p 只查询表视图的当前后代,因此它将循环遍历数据源中总共 n 个单元格中的前 m (m
循环遍历数据源中所有可用单元格的最佳方法是什么?显然查询 .Cell 后代不是正确的方法。
P.S.:每次点击单元格后,我都尝试在表格视图上执行滑动。但是它会滑动到很远的地方(scrollByOffset 不可用)。再说一次,不知道如何从数据源中提取单元格总数。
干杯, 狮子座
【问题讨论】:
【参考方案1】:所以这里的问题是您不能在不可见的单元格上调用 tap()。所以我在XCUIElement上写了一个扩展——XCUIElement+UITableViewCell
func makeCellVisibleInWindow(window: XCUIElement, inTableView tableView: XCUIElement)
var windowMaxY: CGFloat = CGRectGetMaxY(window.frame)
while 1
if self.frame.origin.y < 0
tableView.swipeDown()
else
if self.frame.origin.y > windowMaxY
tableView.swipeUp()
else
break
现在您可以使用此方法使您的单元格可见,然后点击它。
var window: XCUIElement = application.windows.elementBoundByIndex(0)
for i in 0..<tableView.cells.count
let cell = collectionView.cells.elementBoundByIndex(i)
cell.makeCellVisibleInWindow(window, inTableView: tableView)
cell.tap()
backBtn.tap()
【讨论】:
嗨桑迪,感谢您的回复。我认为滑动不是循环遍历表格视图的好主意,因为您无法控制滑动的滚动偏移量。因此,滑动可能会导致在迭代之前将一些单元格移出屏幕。我尝试过的另一种方法是cell.pressForDuration(TapScrollTime, thenDragToElement: prevCell)
——但它也不完美。并且迭代 for i in 0..<tableView.cells.count'
是错误的,因为最初只有几个单元格被加载到表格视图中,但在滚动后会出现新的单元格【参考方案2】:
let cells = XCUIApplication().tables.cells
for cell in cells.allElementsBoundByIndex
cell.tap()
cell.backButton.tap()
【讨论】:
虽然此代码可能会回答问题,但提供有关 why 和/或 如何 回答问题的额外上下文将显着改善其长期价值。请edit你的答案添加一些解释。 根据我的试验,第一个假设告诉你不能点击不可见的单元格对我来说并不正确。我会说它不是 100% 有效,但通常它有效。【参考方案3】:我面临同样的情况,但是根据我的试验,您可以在不可见的单元格上执行 tap()。 但是,它不可靠,并且由于不明原因而失败。 在我看来,这是因为在某些情况下,我在解析表格时想要滚动到的下一个单元格没有加载。
所以这是我使用的技巧: 在解析我的表格之前,我首先在最后一个单元格中点击,在我的情况下,我输入一个可编辑的 UITextField,因为所有其他点击都会导致触发 segue。
第一次点击() 会导致滚动到最后一个单元格,因此会加载数据。
然后我检查我的单元格内容
let cells = app.tables.cells
/*
this is a trick,
enter in editing for last cell of the table view so that all the cells are loaded once
avoid the next trick to fail sometime because it can't find a textField
*/
app.tables.children(matching: .cell).element(boundBy: cells.count - 1).children(matching: .textField).element(boundBy: 0).tap()
app.typeText("\r") // exit editing
for cellIdx in 0..<cells.count
/*
this is a trick
cell may be partially or not visible, so data not loaded in table view.
Taping in it is will make it visible and so do load the data (as well as doing a scroll to the cell)
Here taping in the editable text (the name) as taping elsewhere will cause a segue to the detail view
this is why we just tap return to canel name edidting
*/
app.tables.children(matching: .cell).element(boundBy: cellIdx).children(matching: .textField).element(boundBy: 0).tap()
app.typeText("\r")
// doing my checks
至少到目前为止它对我有用,不确定这是否 100% 有效,例如在很长的列表中。
【讨论】:
以上是关于Xcode 7 ui 自动化 - 通过 tableview/collectionview 循环的主要内容,如果未能解决你的问题,请参考以下文章
在 Xcode 7 UI 自动化中关闭 Touch Id 操作
如何使用 Xcode 7 UI 测试检查表格视图中的单元格是不是可见?
如何通过 Xcode 7 中的 UI 测试在 iOS 应用程序中运行代码?