ios - 使用 XCTest 访问自定义 UIView 中的后代控件

标签 ios swift xcode xib xctest

我遇到的问题是我有包含文本字段的可重用 View /控件。这些是具有自定义 UI View 类的 xib 文件,如下所示:

import UIKit

@IBDesignable
public class CustomControl: UIControl {

  @IBOutlet public weak var textField: UITextField?
  public var contentView: UIView?

  required public init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setupViewFromNib()
  }

  override public init(frame: CGRect) {
    super.init(frame: frame)
    setupViewFromNib()
  }

  override public func awakeFromNib() {
    super.awakeFromNib()
    setupViewFromNib()
  }

  override public func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    setupViewFromNib()
    contentView?.prepareForInterfaceBuilder()
  }

  func setupViewFromNib() {
    guard let view = loadViewFromNib() else { return }
    guard let textField = self.textField else { return }
    view.frame = bounds
    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    addSubview(view)
    contentView = view
  }

  func loadViewFromNib() -> UIView? {
    let selfType = type(of: self)
    let nibName = String(describing: selfType)
    return Bundle(for: selfType)
        .loadNibNamed(nibName, owner: self, options: nil)?
        .first as? UIView
  }
}

这个自定义 View 被加载到 Storyboard中,它们将使用 Storyboard界面生成器使用。

问题是 XCTest 似乎没有为这些 View 的后代建模,所以当我尝试编写一个涉及在作为自定义 View 一部分的文本字段中键入文本的测试时,测试用错误:

Neither element nor any descendant has keyboard focus.

目前的解决方法似乎是点击键盘上的按键而不是使用 typeText 方法。然而,这要慢得多(按键之间的长时间停顿)并且测试代码更麻烦。

所需代码:

let app = XCUIApplication()
let view = app.otherElements["customView"]
let textField = view.textFields["textField"]
textField.tap()
textField.typeText("12345")

使用测试记录我们得到类似的东西:

let app = XCUIApplication()
let view = app.otherElements["customView"]
view.tap()
app.typeText("12345")

但是运行此测试会导致上述错误。

编辑/工作测试变为:

let app = XCUIApplication()
let view = app.otherElements["customView"]
// view appears as a leaf with no descendants
view.tap() 
app.keys["1"].tap()
app.keys["2"].tap()
app.keys["3"].tap()
app.keys["4"].tap()
app.keys["5"].tap()

我也不相信如果自定义 View 包含多个控件,这种变通方法是否仍然可行,例如对于出生日期控制,我希望更精细地控制我正在使用的自定义控件中的哪个字段。

是否有允许我访问自定义 View 中的字段并可能使用 typeText 方法的解决方案?

最佳答案

问题已经解决。正如 Titouan de Bailleul 所建议的那样,问题在于自定义 View 的可访问性已启用,有效地隐藏了其后代文本字段。

将示例项目添加到 Github:

https://github.com/stuartwakefield/XibXCTestIssueSample

谢谢提图安。

关于ios - 使用 XCTest 访问自定义 UIView 中的后代控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45309596/

相关文章:

ios - 使用动画将 uitableview 单元移动到顶部

iphone - iOS:UIView 相对于 UIWindow 的起源

ios - 在 Core Data 中保存 PHAsset?

swift - float 转换崩溃

arrays - 使用数组值初始化新的数组元素

swift - 无法从 ios 13 中的 url 视频生成缩略图

objective-c - 如何以编程方式设置 UIScrollView 框架的大小?

iphone - UIAutomation 脚本示例

ios - SWIFT - BLE 通信

ios - 更新 Xcode 7 后,Facebook sdk 不是 dylib 错误吗?