LoginSignup
12
2

More than 5 years have passed since last update.

XCTestでアニメーションの結果を待つ便利メソッド

Last updated at Posted at 2018-12-16

UIテストをやっていると、アニメーションの実行を待ってからアサートを実行したいときがあります✅
しかし、DispatchQueueのメソッドを使うと、テストの実行自体が止まってしまってアニメーションが実行されなかったり、アニメーションの完了を待たずにテストが終わってしまったり、メインスレッドでは無いスレッドでは描画ができなかったり、なかなか期待する結果になってくれませんでした😭
この記事では、試行錯誤の結果うまく行った便利メソッドを紹介します💡
もしDispatchQueueでもできるよーってことならぜひコメントにて教えていただけると幸いです🙇

(本当はカスタムトランジションについてまとめようかと思っていたけど、時間が無いのでそれは後日・・・)

ディレイメソッド

XCTestExpectationというものを使います。

func delay(testCase: XCTestCase, seconds: Float) {
    let delay = testCase.expectation(description: "animation finished")
    DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(seconds)) {
        delay.fulfill()
    }
    testCase.waitForExpectations(timeout: TimeInterval(seconds + 1.0))
}

短いコードですが、各要素を見ていきます。

func delay(testCase: XCTestCase, seconds: Float) {

引数にはテストクラスそのものと、ディレイさせたい秒数を渡します。

let delay = testCase.expectation(description: "animation finished")

まずはXCTestExpectationを生成します。descriptionは何でもいいです。

DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(seconds)) {
    delay.fulfill()
}

指定された秒数待ったのち、fulfill()を呼び出します。これは期待する結果になったよ、ということを通知するためのメソッドです。
アニメーションはこの待ち時間の間に実行されています。秒数はアニメーションと合わせてください。

testCase.waitForExpectations(timeout: TimeInterval(seconds + 1.0))

念の為、指定された秒数よりちょっと多めにfulfill()が来るのを待ちます。タイムアウトの時間が経過してしまうとテストがFailedになってしまいます。

終わりに

XCTestExpectationについて調べてみたら、APIの取得を待つのに使われている例がいくつか見つかりました🔍
自分はアニメーションを待つために使ったのですが、非同期全般使えるので活躍の機会は多そうです🎉

参考

XCTestExpectation
XCTest入門Part2 (Swift) ~非同期編~
iOS XCTestで非同期処理の完了を待つ

12
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
2