web-dev-qa-db-ja.com

SwiftUIテスト-要素が表示されるのを待つ

テストを一時停止し、要素が画面に表示されるのを待ってから続行したいと思います。

これに対する期待を作成し、使用するのを待つ良い方法がわかりません

public func waitForExpectationsWithTimeout(timeout: NSTimeInterval, handler: XCWaitCompletionHandler?)

私が使ってきた期待を生み出す方法は

public func expectationForPredicate(predicate: NSPredicate, evaluatedWithObject object: AnyObject, handler: XCPredicateExpectationHandler?) -> XCTestExpectation

ただし、これには既存の要素が必要ですが、まだ存在しない要素をテストで待機させたいと思います。

誰かがこれを行うための最良の方法を知っていますか?

13
Alex

expectationForPredicate(predicate: evaluatedWithObject: handler:)では、実際のオブジェクトを指定するのではなく、ビュー階層でオブジェクトを検索するためのクエリを指定します。したがって、たとえば、これは有効なテストです。

let predicate = NSPredicate(format: "exists == 1")
let query = XCUIApplication().buttons["Button"]
expectationForPredicate(predicate, evaluatedWithObject: query, handler: nil)

waitForExpectationsWithTimeout(3, handler: nil)

ヘッダーから生成された I Testing Cheat Sheet および documentation をチェックしてください(現時点では公式のドキュメントはありません)。すべてJoeMasilottiによって作成されました。

18
Tomasz Bąk

これは、Swift 3

func wait(element: XCUIElement, duration: TimeInterval) {
  let predicate = NSPredicate(format: "exists == true")
  let _ = expectation(for: predicate, evaluatedWith: element, handler: nil)

  // We use a buffer here to avoid flakiness with Timer on CI
  waitForExpectations(timeout: duration + 0.5)
}

Xcode 9、iOS 11では、新しいAPI waitForExistenceを使用できます

4
onmyway133

既存の要素は必要ありません。次の述語を定義する必要があります。

let exists = NSPredicate(format: "exists = 1")

次に、この述語を期待どおりに使用します。その後、もちろんあなたの期待を待ちます。

1
sylvanaar

Xcode 8.3以降の場合、新しいクラスXCTWaiterで期待値を待つことができます。テストの例は、次のようになります。

func testExample() {
  let element = // ...
  let predicate = NSPredicate(format: "exists == true")
  let expectation = XCTNSPredicateExpectation(predicate: predicate, object: element)

  let result = XCTWaiter().wait(for: [expectation], timeout: 1)
  XCTAssertEqual(.completed, result)
}

ドキュメントを読む 詳細については。

1
Tomasz Bąk

この質問はSwift2について尋ねられましたが、それでも2019年の上位の検索結果であるため、最新の回答を提供したいと思いました。

Xcode 9.0以降では、 waitForExistence のおかげで、作業が少し簡単になりました。

let app = XCUIApplication()
let myButton = app.buttons["My Button"]
XCTAssertTrue(myButton.waitForExistence(timeout: 10))
sleep(1)
myButton.tap()

WebViewsの例:

let app = XCUIApplication()
let webViewsQuery = app.webViews
let myButton = webViewsQuery.staticTexts["My Button"]
XCTAssertTrue(myButton.waitForExistence(timeout: 10))
sleep(1)
myButton.tap()
1
alanning

onmyway133コード に基づいて拡張機能(Swift 3.2)を思いついた:

extension XCTestCase {
  func wait(for element: XCUIElement, timeout: TimeInterval) {
    let p = NSPredicate(format: "exists == true")
    let e = expectation(for: p, evaluatedWith: element, handler: nil)
    wait(for: [e], timeout: timeout)
  }
}

extension XCUIApplication {
  func getElement(withIdentifier identifier: String) -> XCUIElement {
    return otherElements[identifier]
  }
}

したがって、通話サイトでは次のものを使用できます。

wait(for: app.getElement(withIdentifier: "ViewController"), timeout: 10)
0
rgkobashi