次のテストはiOS11で正常に機能します。ロケーションサービスを使用する許可を求めるアラートを閉じてから、マップを拡大します。 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.3Betaの変更ログには次のように表示されます
XCTest UI割り込みモニターは、iOS 10を実行しているデバイスとシミュレーターで正しく機能するようになりました。(33278282)
_let springboard = XCUIApplication(bundleIdentifier: "com.Apple.springboard")
let allowBtn = springboard.buttons["Allow"]
if allowBtn.waitForExistence(timeout: 10) {
allowBtn.tap()
}
_
_.exists
_を.waitForExistence(timeout: 10)
に更新します。詳細については、コメントを確認してください。
私はこの問題を抱えていました River2202の解決策 私のために働きました。
これはUIInterruptionMonitorを機能させるための修正ではなく、アラートを閉じる別の方法であることに注意してください。 addUIInterruptionMonitorセットアップを削除することもできます。許可アラートが表示される可能性のある場所では、springboard.buttons["Allow"].exists
テストを行う必要があります。可能であれば、forceはテストの初期段階で表示されるため、後で再度心配する必要はありません。
幸い、springboard.buttons["Allow"].exists
コードはiOS11でも機能するため、単一のコードパスを使用でき、iOS10とiOS11で1つのことを行う必要はありません。
ちなみに、私は基本的な問題(addUIInterruptionMonitorがiOS 11より前では機能しない)をAppleのバグとして記録しました。現在、重複としてクローズされているので、バグだと認識していると思います。
@ River2202ソリューション を使用しましたが、中断よりもうまく機能します。それを使うことにした場合は、ウェイター機能を使うことを強くお勧めします。あらゆる種類の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
}