Xcode 7 XCTestで導入されたUIテストAPIを使用しています。画面に、ネットワークから読み込まれたテキストがあります。
exists
プロパティで単純にチェックすると、テストは失敗します。
_XCTAssert(app.staticTexts["Text from the network"].exists) // fails
_
ただし、最初にタップまたはその他のイベントを次のようなテキストに送信すると機能します。
_app.staticTexts["Text from the network"].tap()
XCTAssert(app.staticTexts["Text from the network"].exists) // works
_
exists
を呼び出すだけですぐに評価され、ネットワークからテキストがまだダウンロードされていないため失敗します。しかし、tap()
メソッドを呼び出すと、テキストが表示されるのを待ちます。
ネットワークから配信されるテキストの存在を確認するより良い方法はありますか?
次のようなもの(このコードは機能しません):
_XCTAssert(app.staticTexts["Text from the network"].eventuallyExists)
_
Xcode 7 Beta 4では、非同期イベントのネイティブサポートが追加されました。 UILabel
が表示されるのを待つ簡単な例を次に示します。
XCUIElement *label = self.app.staticTexts[@"Hello, world!"];
NSPredicate *exists = [NSPredicate predicateWithFormat:@"exists == 1"];
[self expectationForPredicate:exists evaluatedWithObject:label handler:nil];
[self waitForExpectationsWithTimeout:5 handler:nil];
最初に、テキスト「Hello、world!」のラベルを待つクエリを作成します。現れる。要素が存在する場合、述語は一致します(element.exists == YES)
。次に、述語を渡し、ラベルに対して評価します。
期待値が満たされる前に5秒経過すると、テストは失敗します。また、予期が失敗したりタイムアウトしたりしたときに呼び出されるハンドラブロックをアタッチすることもできます。
UIテスト全般に関する詳細情報をお探しの場合は、 Xcode 7のUIテスト をご覧ください。
XCode9にはメソッド waitForExistence(timeout:TimeInterval) of XCUIElement
があります
extension XCUIElement {
// A method for tap element
@discardableResult
func waitAndTap() -> Bool {
let _ = self.waitForExistence(timeout: 10)
let b = self.exists && self.isHittable
if (b) {
self.tap()
}
return b
}
}
// Ex:
if (btnConfig.waitAndTap() == true) {
// Continue UI automation
} else {
// `btnConfig` is not exist or not hittable.
}
しかし、別の問題が発生しました。element
は存在しますが、ヒット可能ではありません。そのため、要素がヒット可能になるのを待つメソッドを拡張します。
extension XCTestCase {
/// Wait for XCUIElement is hittable.
func waitHittable(element: XCUIElement, timeout: TimeInterval = 30) {
let predicate = NSPredicate(format: "isHittable == 1")
expectation(for: predicate, evaluatedWith: element, handler: nil)
waitForExpectations(timeout: timeout, handler: nil)
}
}
// Ex:
// waitHittable(element: btnConfig)
Swift 3:
let predicate = NSPredicate(format: "exists == 1")
let query = app!.staticTexts["identifier"]
expectation(for: predicate, evaluatedWith: query, handler: nil)
waitForExpectations(timeout: 5, handler: nil)
そのテキストが表示されているかどうかを5秒間継続的にチェックします。
テキストが5秒未満であることがわかるとすぐに、それはさらにコードを実行します。
ターゲットテキストが存在することを確認しているときに、そのテキストがすでに表示されていることを理解しているのであれば、hittable
プロパティを使用してみてください。