可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
The following tests works fine on iOS 11. It dismisses the alert asking permissions to use the locations services and then zooms in in the map. On iOS 10 or 9, it does none of this and the test still succeeds
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) }
Does anyone have an idea why and/or a workaround?
Here's a project where you can reproduce the issue: https://github.com/TitouanVanBelle/Map
Update
Xcode 9.3 Beta's Changelogs show the following
XCTest UI interruption monitors now work correctly on devices and simulators running iOS 10. (33278282)
回答1:
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") let allowBtn = springboard.buttons["Allow"] if allowBtn.exists { allowBtn.tap() }
回答2:
I had this problem and River2202's solution worked for me.
Note that this is not a fix to get the UIInterruptionMonitor to work, but a different way of dismissing the alert. You may as well remove the addUIInterruptionMonitor setup. You'll need to have the springboard.buttons["Allow"].exists
test anywhere the permission alert could appear. If possible, force it to appear at an early stage of the testing so you don't need to worry about it again later.
Happily the springboard.buttons["Allow"].exists
code still works in iOS 11, so you can have a single code path and not have to do one thing for iOS 10 and another for iOS 11.
Incidentally, I logged the base issue (that addUIInterruptionMonitor is not working pre-iOS 11) as a bug with Apple. It has been closed as a duplicate now, so I guess they acknowledge that it is a bug.
回答3:
I used the @River2202 solution and it works better instead of interruption one. If you decide to use that,, I strong suggest to use a waiter function,, I created this one in order to wait any kind on XCUIElement appears:
Try it!
// 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 wich returns: 'Waiters can be used with or without a delegate to respond to events such as completion, timeout, or invalid expectation fulfillment.' @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
}