以下测试在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 interruption monitors now work correctly on devices and simulators running iOS 10. (33278282)
答案 0 :(得分:23)
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
let allowBtn = springboard.buttons["Allow"]
if allowBtn.waitForExistence(timeout: 10) {
allowBtn.tap()
}
将.exists
更新为.waitForExistence(timeout: 10)
,详情请查看评论。
答案 1 :(得分:3)
我遇到了这个问题,River2202's solution为我工作。
请注意,这不是让UIInterruptionMonitor工作的解决方法,而是一种解除警报的不同方法。您也可以删除addUIInterruptionMonitor设置。您需要在可能出现权限警报的任何地方进行springboard.buttons["Allow"].exists
测试。如果可能的话,强制它会在测试的早期阶段出现,所以您以后不必再担心它。
令人高兴的是,springboard.buttons["Allow"].exists
代码仍可在iOS 11中运行,因此您可以使用单个代码路径,而不必为iOS 10执行一项操作,而为iOS 11执行另一项操作。
顺便说一句,我记录了基本问题(addUIInterruptionMonitor在iOS 11之前不工作)作为Apple的错误。它现在已经关闭了,所以我猜他们承认这是一个错误。
答案 2 :(得分:1)
我使用了@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
}