【问题标题】:XCode 7 UI Testing: Dismissal of system-generated UIAlertController does not workXCode 7 UI 测试:关闭系统生成的 UIAlertController 不起作用
【发布时间】:2016-01-12 11:22:01
【问题描述】:

我有一个 UI 测试,其中涉及解除系统生成的 UIAlertController。此警报要求用户授予访问设备日历的权限。测试的目标是点击OK 按钮后的行为:

1 let app = XCUIApplication()
...
// this code was basically generated by the recording feature of XCode 7 
2 app.alerts.elementBoundByIndex(0).collectionViews.buttons["OK"].tap()

现在,第 2 行不是单击 OK 按钮,而是让模拟器点击第一个按钮,恰好是 Cancel 按钮...

此外,我发现测试框架无法准确识别出现的警报。因此,如果我检查当前的警报计数,我总是得到 0:

// ...tap...
let count = app.alerts.count // == 0

如果我使用NSPredicate 作为条件并等待几秒钟,也会发生这种情况。

UI 测试是否可能无法可靠地处理系统生成的警报?我正在使用 XCode 7.0.1。

【问题讨论】:

  • 通过 UI 测试与系统警报交互是 known bug/issue
  • 天啊! XCode 7 错误检测之旅似乎是一个永无止境的故事......
  • 不再是了,哇!查看my answer below。 :-)

标签: xcode7 uialertcontroller ui-testing xcode-ui-testing


【解决方案1】:

我设法关闭了这样的联系人的访问提示:

let alert = app.alerts["\u{201c}******\u{201d} Would Like to Access Your Contacts"].collectionViews.buttons["OK"]
if alert.exists
{
    alert.tap()
}

用您的应用名称替换星号。它可能对日历同样有效。

这就是我最终用来让提示出现然后允许访问联系人的方法:

func allowAccessToContacts(textFieldsName: String)
{
    let app = XCUIApplication()

    let textField = app.textFields[textFieldsName]
    textField.tap()
    textField.typeText("aaa")

    let alert = app.alerts["\u{201c}******\u{201d} Would Like to Access Your Contacts"].collectionViews.buttons["OK"]
    if alert.exists
    {
        alert.tap()
    }
    textField.typeText("\u{8}\u{8}\u{8}")
}

【讨论】:

    【解决方案2】:

    Xcode 7.1 终于修复了系统警报问题。但是,有两个小问题。

    首先,您需要在显示警报之前设置“UI 中断处理程序”。这是我们告诉框架如何处理出现的警报的方式。

    其次,在呈现警报后,您必须与界面进行交互。只需点按应用即可,但这是必需的。

    addUIInterruptionMonitorWithDescription("Location Dialog") { (alert) -> Bool in
        alert.buttons["Allow"].tap()
        return true
    }
    
    app.buttons["Request Location"].tap()
    app.tap() // need to interact with the app for the handler to fire
    

    “位置对话框”只是帮助开发人员识别访问了哪个处理程序的字符串,它不特定于警报类型。我相信从处理程序返回true 会将其标记为“完成”,这意味着它不会再次被调用。

    【讨论】:

    • 您是否尝试过关闭该行中的多个不同警报?我试图弄清楚。但是,它比仅仅注册多个中断监视器(以相反的顺序)更复杂
    • 乔,谢谢分享。发射时的连续警报呢?我有一个要求位置,然后就在此之后要求推送通知。使用您的方法,我可以很好地解雇第一个,但第二个不会再次触发addUIInterruptionMonitorWithDescription。有什么想法吗?
    • 我会推荐app.coordinateWithNormalizedOffset(CGVector(dx: 200, dy: 1)).tap() 而不是app.tap(),因为它可以点击你不期望的东西,就像我的例子一样,并打破进一步的测试流程。
    • @VladimirTolstikov +1 这真的发生在我身上,好电话
    • 我会把关于点击所需的“第二部分”以粗体或第一部分表示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    • 2016-02-25
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    相关资源
    最近更新 更多