【问题标题】:addUIInterruptionMonitor(withDescription:handler:) not working on iOS 10 or 9addUIInterruptionMonitor(withDescription:handler:) 在 iOS 10 或 9 上不起作用
【发布时间】:2017-12-26 22:55:57
【问题描述】:

以下测试在 iOS 11 上运行良好。它会关闭询问权限以使用位置服务的警报,然后放大地图。在 iOS 10 或 9 上,它什么都不做,测试仍然成功

func testExample() {
    let app = XCUIApplication()

    var handled = false
    var appeared = false

    let token = addUIInterruptionMonitor(withDescription: "Location") { (alert) -> Bool in
        appeared = true
        let allow = alert.buttons["Allow"]
        if allow.exists {
            allow.tap()
            handled = true
            return true
        }

        return false
    }

    // Interruption won't happen without some kind of action.
    app.tap()

    removeUIInterruptionMonitor(token)
    XCTAssertTrue(appeared && handled)
}

有人知道原因和/或解决方法吗?

这是一个可以重现该问题的项目:https://github.com/TitouanVanBelle/Map

更新

Xcode 9.3 Beta 的变更日志显示以下内容

XCTest UI 中断监视器现在可以在运行 iOS 10 的设备和模拟器上正常工作。(33278282)

【问题讨论】:

    标签: ios swift xctest xcode-ui-testing


    【解决方案1】:
    let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") 
    
    let allowBtn = springboard.buttons["Allow"]
    if allowBtn.waitForExistence(timeout: 10) {
        allowBtn.tap()
    }
    

    .exists更新为.waitForExistence(timeout: 10),详情请查看cmets。

    【讨论】:

    • 我不敢相信这行得通:)谢谢!但是,我宁愿通过索引访问按钮,否则在不同的iOS版本中将无法使用(iOS 11中按钮标题发生了变化)
    • 使用addUIInteruptionMonitor() 无法消除SFAuthenticationSession 警报,但这种技术对我们有用。
    • 这对我测试tel: URL 方案很有用。 addUIInteruptionMonitor 没有找到 iOS 生成的警报。
    • 这对我来说不是开箱即用的。但是当我用.waitForExistence(timeout: 10) 替换.exists 时,它起作用了。
    • @ChristianBeer 感谢分享。是的,我们也有同样的问题。似乎.exist 在最新的 Xcode 中真正的 UI 出现在屏幕上之前返回 true。 .waitForExistence 在这种情况下确实有所帮助。
    【解决方案2】:

    我使用了@River2202 solution,它比中断的效果更好。 如果您决定使用它,我强烈建议您使用服务员功能。我创建这个是为了等待任何类型的 XCUIElement 出现:

    试试吧!

    // function to wait for an ui element to appear on screen, with a default wait time of 20 seconds
    // XCTWaiter was introduced after Xcode 8.3, which is handling better the timewait, it's not failing the test.  It uses an enum which returns: 'Waiters can be used with or without a delegate to respond to events such as completion, timeout, or invalid  expectation fulfilment.'
    @discardableResult
    func uiElementExists(for element: XCUIElement, timeout: TimeInterval = 20) -> Bool {
        let expectation = XCTNSPredicateExpectation(predicate: NSPredicate(format: "exists == true"), object: element)
        let result = XCTWaiter().wait(for: [expectation], timeout: timeout)
        guard result == .completed else {
            return false
        }
        return true
    }
    

    【讨论】:

      【解决方案3】:

      我遇到了这个问题,River2202's solution 为我工作。

      请注意,这不是让 UIInterruptionMonitor 工作的修复方法,而是一种解除警报的不同方式。您也可以删除 addUIInterruptionMonitor 设置。您需要在可能出现权限警报的任何地方进行springboard.buttons["Allow"].exists 测试。如果可能,强制它出现在测试的早期阶段,这样您以后就不必再担心了。

      很高兴springboard.buttons["Allow"].exists 代码在 iOS 11 中仍然有效,因此您可以拥有单一的代码路径,而不必为 iOS 10 做一件事情,而为 iOS 11 做另一件事情。

      顺便说一句,我将基本问题(addUIInterruptionMonitor 在 iOS 11 之前的版本中无法正常工作)记录为 Apple 的错误。它现在已作为副本关闭,所以我猜他们承认这是一个错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-03
        • 2015-12-14
        • 1970-01-01
        • 2016-02-21
        • 2013-11-01
        相关资源
        最近更新 更多