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 的视图),则其所有子视图都将无法访问。这同样适用于UITableViewUITableViewCell。但是您可以设置它们的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(boun‌​dBy:2).button["detai‌​lButton"].tap() 恐怕它会搜索两个表并获取所有元素。然后,如果您使用 element(boundBy: Int) 它将所有单元格放在一个数组中,并在索引 2 上取一个。但我不确定我是否理解正确。你能给我更多关于视图层次结构和你想选择哪个单元格/你想从单元格中读取什么的详细信息吗?尝试使用新的详细信息编辑您的问题。我会尽力帮忙的。

以上是关于XCUITest 无法检测到我动态生成的 tableView 的可访问性 id的主要内容,如果未能解决你的问题,请参考以下文章

XCUITest 和动态生成的视图

XCUITest:与具有许多单元格的表格进行交互

unity诡异的问题---使用脚本动态生成的物体无法用射线检测到,但是进入攻击范围后又可以被检测到

XCUITest 使用 adjustToPickerWheelValue: && viewForRow: 委托导致断言

XCUITest 无法识别警报

XCUITest 元素快照无法闪烁光标