XCUITesting权限弹出:出现警报,但UIInterruptionMonitor不会触发

Qui*_*ana 8 ios swift xcode-ui-testing xcode7.2

我想写一个这样的测试:

当我的应用程序转到某个窗格时,它应该请求使用相机的权限.

我想测试窗格是否出现.我正在使用XC的内置UITest框架来执行此操作.根据我在谷歌和这里发现的,似乎我应该做以下事情:

let dialogAppearedExpectation = expectationWithDescription("Camera Permission Dialog Appears")

addUIInterruptionMonitorWithDescription("Camera Permission Alert") { (alert) -> Bool in
    dialogAppearedExpectation.fulfill()
    return true
}

goToCameraPage()

waitForExpectationsWithTimeout(10) { (error: NSError?) -> Void in
    print("Error: \(error?.localizedDescription)")
}
Run Code Online (Sandbox Code Playgroud)

测试始于失败,很棒.我实现了goToCameraPage,它正确地导致出现"给予权限"弹出窗口.但是,我希望这会触发中断监视器.然而,没有捕获到这样的中断,并且不会发生履行.

我在某个地方读到app.tap()了对话框出现后你应该做的事情.但是,当我这样做时,它会单击"允许"按钮.对话框消失,仍然没有处理中断.

是否有某种方式将权限对话框视为"警报"或无法处理?我甚至进入并用一个看起来的东西替换了中断位app.alerts,但结果是空的,即使我正在看模拟器中的弹出窗口.

谢谢!我正在为iPhone 6s使用Xcode7.2,iOS 9.2模拟器.

Doe*_*ata 8

所以煎饼的回答对我有用。不过,我认为可以简化。呈现系统警报时,似乎确实存在某种奇怪的死锁或竞争条件。

\n\n

而不是NSPredicate我刚刚sleep(2)在系统警报应该出现之后和尝试之前使用的期望XCUIApplication().tap()

\n\n

我也决定使用它,XCUIApplication().swipeUp()因为它不太可能干扰测试。

\n\n

使用 Facebook 登录的示例

\n\n
class LoginWithFacebookTest: XCTestCase {\n\n    let app = XCUIApplication()\n\n    var interruptionMonitor: NSObjectProtocol!\n    let alertDescription = "\xe2\x80\x9cAPP_NAME\xe2\x80\x9d Wants to Use \xe2\x80\x9cfacebook.com\xe2\x80\x9d to Sign In"\n\n    override func setUp() {\n        super.setUp()\n    }\n\n    override func tearDown() {\n        super.tearDown()\n        self.removeUIInterruptionMonitor(interruptionMonitor)\n    }\n\n    func loginWithFacebookTest() {\n        app.launch()\n\n        self.interruptionMonitor = addUIInterruptionMonitor(withDescription: self.alertDescription) { (alert) -> Bool in\n            // check for a specific button\n            if alert.buttons["Continue"].exists {\n                alert.buttons["Continue"].tap()\n                return true\n            }\n\n            return false\n        }\n\n        let loginWithFacebook = app.otherElements["login with facebook"]\n        loginWithFacebook.tap()\n\n        // Sleep to give the alert time to show up\n        sleep(2)\n\n        // Interact with the app to get the above monitor to fire\n        app.swipeUp()\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n


pan*_*ake 6

我也注意到了这个问题.看起来中断处理程序是异步运行的,并且没有办法断言它们是否被调用.等待期望似乎也阻止了中断监视器的运行.看起来系统正在等待期望实现并期望等待中断监视器触发.一个经典的死锁案例.

但是,我发现了一个使用NSPredicate基于预期的相当古怪的解决方案:

var didShowDialog = false
expectation(for: NSPredicate() {(_,_) in
    XCUIApplication().tap() // this is the magic tap that makes it work
    return didShowDialog
}, evaluatedWith: NSNull(), handler: nil)

addUIInterruptionMonitor(withDescription: "Camera Permission Alert") { (alert) -> Bool in
    alert.buttons.element(boundBy: 0).tap() // not sure if allow = 0 or 1
    didShowDialog = true
    return true
}

goToCameraPage()

waitForExpectations(timeout: 10) { (error: Error?) -> Void in
    print("Error: \(error?.localizedDescription)")
}
Run Code Online (Sandbox Code Playgroud)

显然,XCUIApplication().tap()即使测试用例正在等待期望,在谓词块内部以某种方式允许运行中断监视器.

我希望这对你有用,就像对我一样!