UI 测试 - isSelected 总是返回 false
UI Tests - isSelected is always returning false
我们最近使用 Xcode 8.2.1 (8C1002) 将 Swift 2.3 项目更新为 Swift 3,现在我们的大部分 UI 测试与table视图和 isSelected 属性 不工作。它总是返回 false,即使选择了对象(我们可以在 iOS 模拟器中看到它)。
有没有人遇到过类似的问题?在转换之前,我们的代码在 Swift 2.3 中可以正常工作。以下是我们如何检索 tableView 单元格:
let cell = app.tables.cells.element(at: 4)
注意: app
是一个 XCUI 应用程序。
下面是我们检查它是否被选中的方法:
XCTAssert(cell.isSelected)
另一个观察结果是我们确定该对象存在,因为 waitForExpectations
返回 true:
let existsPredicate = NSPredicate(format: "exists = 1")
expectation(for: existsPredicate, evaluatedWith: cell, handler: nil)
waitForExpectations(timeout: 20, handler: nil)
编辑: 为了替换 isSelected
,我尝试将 NSPredicate 与 selected = 1
和 isSelected = 1
一起使用。 None 成功了。我还尝试根据其他问题的答案使用 acessibilityValue
,但这并不是那么简单,因为有时我的 table 视图中的项目是 selected/unselected 编程的。此外,该方法涉及向应用程序添加测试代码,这不是一个好的做法。
赏金结束后编辑: 由于没有人能找到解决该问题的方法,而且这显然是 Xcode 中的错误,我已将错误报告提交给苹果。当他们发布带有修复的 Xcode 版本时,我会在这里发表评论。
额外编辑: 在我上次编辑一天后,dzoanb 给出了一个实用的答案。
你试过在点击前后打断点,查看单元格的值吗?喜欢这里的 WWDC 视频:https://youtu.be/7zMGf-0OnoU
(从10分钟开始看)
isSelected
仅适用于继承自 UIControl
的视图。 UIControl.isSelected
通知 XCUIElement.isSelected
.
由于 UITableViewCell
没有继承自 UIControl
,当您观察 cell.isSelected
.
时,您在测试中看不到想要的值
我建议,如果你想通过 UI 测试来测试它,你可以向 Apple 提交功能请求以制定 UIControl
协议,然后你可以扩展你的单元格以符合,或将 UITableViewCell.isSelected
添加到通知 XCUIElement.isSelected
.
的属性
我做了一些测试和一些研究。您可以查看为此目的创建的应用 >>here<<. It would be great if you could check it out (it required a little bit of work). There are also UI tests to prove it works. Also, two options are available, one is vanilla XCTest and one library with a lot of helpers I'm creating with my colleagues AutoMate。但这不是重点。
这是我发现的:
1) isSelected
属性 of XCUIElement
取决于 accessibilityTrait
。要在 XCTest 中选择的元素必须设置 UIAccessibilityTraitSelected
。
2) 我无法重现您的问题,但我能够控制 isSelected
属性.
3) 是的,它需要一些代码,但如果它对您很重要,应该可以很好地与 VoiceOver 配合使用。
所有必要的代码都在您的自定义 UITableViewCell
子类中。并使用覆盖 UIAccessibilityElement
accessibilityTraits
属性.
private var traits: UIAccessibilityTraits = UIAccessibilityTraitNone
// MARK: UITableViewCell life cycle
override func awakeFromNib() {
super.awakeFromNib()
traits = super.accessibilityTraits
}
// MARK: UIAccessibilityElement
override var accessibilityTraits: UIAccessibilityTraits {
get {
if isSelected {
return traits | UIAccessibilityTraitSelected
}
return traits
}
set {
traits = newValue
}
}
希望对您有所帮助。
@dzoanb 解决方案可以在不添加私有变量的情况下工作:
override var accessibilityTraits: UIAccessibilityTraits {
get {
if isSelected {
return super.accessibilityTraits | UIAccessibilityTraitSelected
}
return super.accessibilityTraits
}
set {
super.accessibilityTraits = newValue
}
}
无法在 Swift 4 下编译该代码。
这对我有用。
public override var accessibilityTraits: UIAccessibilityTraits {
get {
if isSelected {
return super.accessibilityTraits.union(.selected)
}
return super.accessibilityTraits
}
set {
super.accessibilityTraits = newValue
}
}
我们最近使用 Xcode 8.2.1 (8C1002) 将 Swift 2.3 项目更新为 Swift 3,现在我们的大部分 UI 测试与table视图和 isSelected 属性 不工作。它总是返回 false,即使选择了对象(我们可以在 iOS 模拟器中看到它)。
有没有人遇到过类似的问题?在转换之前,我们的代码在 Swift 2.3 中可以正常工作。以下是我们如何检索 tableView 单元格:
let cell = app.tables.cells.element(at: 4)
注意: app
是一个 XCUI 应用程序。
下面是我们检查它是否被选中的方法:
XCTAssert(cell.isSelected)
另一个观察结果是我们确定该对象存在,因为 waitForExpectations
返回 true:
let existsPredicate = NSPredicate(format: "exists = 1")
expectation(for: existsPredicate, evaluatedWith: cell, handler: nil)
waitForExpectations(timeout: 20, handler: nil)
编辑: 为了替换 isSelected
,我尝试将 NSPredicate 与 selected = 1
和 isSelected = 1
一起使用。 None 成功了。我还尝试根据其他问题的答案使用 acessibilityValue
,但这并不是那么简单,因为有时我的 table 视图中的项目是 selected/unselected 编程的。此外,该方法涉及向应用程序添加测试代码,这不是一个好的做法。
赏金结束后编辑: 由于没有人能找到解决该问题的方法,而且这显然是 Xcode 中的错误,我已将错误报告提交给苹果。当他们发布带有修复的 Xcode 版本时,我会在这里发表评论。
额外编辑: 在我上次编辑一天后,dzoanb 给出了一个实用的答案。
你试过在点击前后打断点,查看单元格的值吗?喜欢这里的 WWDC 视频:https://youtu.be/7zMGf-0OnoU (从10分钟开始看)
isSelected
仅适用于继承自 UIControl
的视图。 UIControl.isSelected
通知 XCUIElement.isSelected
.
由于 UITableViewCell
没有继承自 UIControl
,当您观察 cell.isSelected
.
我建议,如果你想通过 UI 测试来测试它,你可以向 Apple 提交功能请求以制定 UIControl
协议,然后你可以扩展你的单元格以符合,或将 UITableViewCell.isSelected
添加到通知 XCUIElement.isSelected
.
我做了一些测试和一些研究。您可以查看为此目的创建的应用 >>here<<. It would be great if you could check it out (it required a little bit of work). There are also UI tests to prove it works. Also, two options are available, one is vanilla XCTest and one library with a lot of helpers I'm creating with my colleagues AutoMate。但这不是重点。
这是我发现的:
1) isSelected
属性 of XCUIElement
取决于 accessibilityTrait
。要在 XCTest 中选择的元素必须设置 UIAccessibilityTraitSelected
。
2) 我无法重现您的问题,但我能够控制 isSelected
属性.
3) 是的,它需要一些代码,但如果它对您很重要,应该可以很好地与 VoiceOver 配合使用。
所有必要的代码都在您的自定义 UITableViewCell
子类中。并使用覆盖 UIAccessibilityElement
accessibilityTraits
属性.
private var traits: UIAccessibilityTraits = UIAccessibilityTraitNone
// MARK: UITableViewCell life cycle
override func awakeFromNib() {
super.awakeFromNib()
traits = super.accessibilityTraits
}
// MARK: UIAccessibilityElement
override var accessibilityTraits: UIAccessibilityTraits {
get {
if isSelected {
return traits | UIAccessibilityTraitSelected
}
return traits
}
set {
traits = newValue
}
}
希望对您有所帮助。
@dzoanb 解决方案可以在不添加私有变量的情况下工作:
override var accessibilityTraits: UIAccessibilityTraits {
get {
if isSelected {
return super.accessibilityTraits | UIAccessibilityTraitSelected
}
return super.accessibilityTraits
}
set {
super.accessibilityTraits = newValue
}
}
无法在 Swift 4 下编译该代码。 这对我有用。
public override var accessibilityTraits: UIAccessibilityTraits {
get {
if isSelected {
return super.accessibilityTraits.union(.selected)
}
return super.accessibilityTraits
}
set {
super.accessibilityTraits = newValue
}
}