XCUITest 无法检测到我动态生成的 tableView 的可访问性 id
Posted
技术标签:
【中文标题】XCUITest 无法检测到我动态生成的 tableView 的可访问性 id【英文标题】:XCUITest cannot detect the accessibility id of my dynamically generated tableView 【发布时间】:2017-05-05 19:09:46 【问题描述】:我正在使用 XCUIApplication 编写 UI 测试。我正在测试单元格行上的选定索引。当我运行测试时,我无法获取所选索引的文本。但是,我可以单击选定的行,但使用底部 tableView 的静态文本。当下面有一个 tableViewController 时会发生这种情况。我正在尝试在另一个 TableViewController 之上添加一个带有 tableView 的 ViewController。下面的tableViewController是使用storyboard生成的,上面的viewController是动态生成的。
设置:我正在为 tableView 的行使用 xib,并且正在使用带有标签和图像的自定义 UITableViewCell。标签和图像都打开了可访问性,但单元格没有打开。我已尝试在单元格上打开可访问性,但仍然无法正常工作。
这是我的测试
//the BoxListTable is my ViewController that is on top
// I added the following code in that viewController:
self.view.isAccessibilityElement = true
self.view.accessibilityIdentifier = "BoxListTable"
//I also added these for the tableView but it doesn't show up in my tests
tableView.accessibilityIdentifier = "tableview"
tableView.isAccessibilityElement = true
//my test is the following
XCUIApplication().tables["BoxListTable"].tap()
当我运行此测试时,测试单击完整的 tableView 但无法获取任何静态文本。它也无法获取任何单元格或表格视图。 po XCUIApplication.tables["BoxListTable"].cells.count 它返回 0。 //我试过 XCUIApplication.tables["BoxListTable"].element.children(匹配:.other) 返回 0
能否请您告诉我为什么即使设置了accessibilityIdentifier,我也看不到它。
【问题讨论】:
我在SkyFloatingLabelTextField 上遇到了类似的问题,否则很好。我无法访问它提供的任何子视图... 当你做po XCUIApplication().tables
时你会得到什么?你的视图控制器上self.view
的类类型是什么?
@Oletha 当我执行 po XUIApplication().tables 时,我得到了当前显示的所有表,但它不包括视图中的表视图。我只能参考下面的tableView。 XCUIApplication().tables.count 返回 1
【参考方案1】:
首先,如果您在父视图上打开isAccessibilityElement
标志(在您的情况下是BoxListTable
的视图),则其所有子视图都将无法访问。这同样适用于UITableView
和UITableViewCell
。但是您可以设置它们的accessibilityIdentifiers
,它们将对所有 UI 元素可见,即使是那些将 isAccessibilityElement
评估为 false
的元素。
所以有这个纯 XCTest 版本,但它仅适用于已加载的单元格(所有延迟加载的单元格都不可用)并且可能会被键盘或导航栏挡住。此外,如果您在不对其执行任何操作的情况下查找元素的内容,框架本身将不会滚动到该元素。因此,检查视图 exists
是否会通过但 isHittable
会失败,因为该元素可能不在用户可以看到的区域之外。
let app = XCIUApplication()
let selectedCell: XCUIElement = table.cells.element(matching: NSPredicate(format: "isSelected == true"))
selectedCell.tap() // If you want to make sure framework will scroll to it.
selectedCell.staticTexts["yourText"]
// or
selectedCell.staticTexts.element(boundBy: index)
我鼓励你尝试使用AutoMate 库,它可以为你省去以上所有的麻烦。
let app = XCIUApplication()
let selectedCell: XCUIElement = table.cells.element(matching: NSPredicate(format: "isSelected == true"))
XCTAssertFalse(selectedCell.isVisible) // `isVisible` checks if element exists in hierarchy and is visible to the user.
table.swipe(to: .down, untilVisible: selectedCell, from: app)
XCTAssertTrue(selectedCell.isVisible)
要了解所有这些方法的工作原理,请查看我制作的示例应用程序 >>here<<。
如果您发现XCUIElement
上的isSelected
属性有任何问题,您应该查看我对>>this question<< 的回答。正如您在示例应用程序中看到的那样,我遇到了这个问题(Xcode 版本 8.3.2 (8E2002))。
【讨论】:
顺便说一句,设置isAccessibilityElement = false
真的让我在一个相关的 UI 测试问题上度过了愉快的一天……非常感谢您的提示 :)
感谢您的帮助,在父视图上设置 isAccessibilityElement = false 就可以了。
@dzoanb 感谢您的帮助,设置 isAccessibilityElement = false 。我认为它成功了,但是当底部的 TableView 为空时,我得到了这个XCUIApplication.tables["Empty list"]
。如果底部表格中有行,它会选择XCUIApplication.tables.children(matching:.cell).element(boundBy:2).button["detailButton"].tap()
。但是,此选择适用于底部单元格,但它获取顶部单元格上的热点,而不是行索引。
@user2263712 我不确定我是否理解正确。您是否在一个视图中有 2 个表? XCUIApplication.tables.children(matching:.cell).element(boundBy:2).button["detailButton"].tap()
恐怕它会搜索两个表并获取所有元素。然后,如果您使用 element(boundBy: Int) 它将所有单元格放在一个数组中,并在索引 2 上取一个。但我不确定我是否理解正确。你能给我更多关于视图层次结构和你想选择哪个单元格/你想从单元格中读取什么的详细信息吗?尝试使用新的详细信息编辑您的问题。我会尽力帮忙的。以上是关于XCUITest 无法检测到我动态生成的 tableView 的可访问性 id的主要内容,如果未能解决你的问题,请参考以下文章
unity诡异的问题---使用脚本动态生成的物体无法用射线检测到,但是进入攻击范围后又可以被检测到