iOS
XCTest
Swift

XCTest入門Part2 (Swift) ~非同期編~

More than 1 year has passed since last update.


はじめに

今回は、XCTestで非同期処理のテストをしてみます。

ちなみに、前回はXCTestの基礎を記載しました。

http://qiita.com/okuderap/items/97f9d6026d0da59fef38

こちらも参考にしてみてください。

XCTestでカバレッジを確認する方法

http://qiita.com/okuderap/items/de574685592fe0bee8ea


非同期処理のテスト

XCTestでは非同期処理のテストをすることもできるんです。

非同期処理のテストにはXCTestExpectationを使います。

let imageDownloadExpectation: XCTestExpectation? = 

self.expectationWithDescription("download Image")

こんな感じで定義してあげます。テストコードの中に複数のexpectationを定義することもできます。

descriptionには、非同期処理の期待する結果を書いてあげれば良いかと。

期待する結果になったところで

XCTestExpectationのfulfillを呼びます。

imageDownloadExpectation?.fulfill()

それから、タイムアウトの時間を決めます。

waitForExpectationsWithTimeout(timeout: 0.05, handler:nil)

こんな感じでタイムアウトの設定をします。handlerは、今回はnilにしておきます。

定義したXCTestExpectationの数分だけfulfillが呼ばれて

且つタイムアウトしていなければtest Succeededとなります。

どちらか一方でも条件を満たすことができなければtest Failedとなってしまいます。


テストしてみる


テスト対象のメソッド

今回は、以下のメソッドをテストしてみたいと思います。


UrlSessionManager.swift

    func downloadImage(urlString: String,

completionHandler: ((NSData?, NSURLResponse?, NSError?) -> Void)) {

guard let url = NSURL(string: urlString) else {
return
}
let request = NSURLRequest(URL: url)

let session = NSURLSession(configuration: .defaultSessionConfiguration())
let task = session.dataTaskWithRequest(request, completionHandler: completionHandler)

task.resume()
}



テストコードを書いてみる

実際にテストコードを書いてみます。

ポイントとなるのは上述の通り

- XCTestExpectationの定義

- XCTestExpectationのfulfill呼び出し

- waitForExpectationsWithTimeoutでタイムアウトの設定

こんな感じです。

また、定義したXCTestExpectationの数分だけfulfillを呼ぶということも重要です。

(私は、はじめtest用urlの配列の長さ分だけループさせていたためfulfillを複数回呼んでtest Failedとなっていました。気づくのにしばらくかかった、、)


UrlSessionManagerTests.swift

import XCTest

@testable import SwiftXCTestSample

class UrlSessionManagerTests: XCTestCase {
let urlSessionManager = UrlSessionManager()

override func setUp() {
super.setUp()
}

override func tearDown() {
super.tearDown()
}

func testDownloadImage() {

let imageDownloadExpectation: XCTestExpectation? = self.expectationWithDescription("download Image")

let urlString = "http://www.smartdt.jp/images/common/logo.png"
urlSessionManager.downloadImage(urlString, completionHandler:{ (data, response, error) in
XCTAssertNil(error)
XCTAssertNotNil(data)
imageDownloadExpectation?.fulfill()
})
self.waitForExpectationsWithTimeout(0.02, handler: nil)
}


こんな感じのコードで非同期処理のテストをすることができます。


せっかくなのでパフォーマンステストも書いてみる

せっかく非同期処理のテストをするので、パフォーマンステストもしてみます。

パフォーマンステストについては、前回のXCTest入門Part1でも軽く触れたので詳細説明は割愛させていただきます。


UrlSessionManagerTests.swift

func testPerformanceDownloadImage() {

self.measureBlock { [weak self] () in
guard let weakSelf = self else {
return
}

let imageDownloadExpectation: XCTestExpectation? = weakSelf.expectationWithDescription("download Image")
let testUrlString = "http://www.smartdt.jp/images/common/logo.png"

weakSelf.urlSessionManager.downloadImage(testUrlString, completionHandler:{ (data, response, error) in
XCTAssertNil(error)
XCTAssertNotNil(data)
imageDownloadExpectation?.fulfill()
})
weakSelf.waitForExpectationsWithTimeout(0.02, handler: nil)

}
}



さいごに

今回はXCTestで非同期処理のテストをする方法を書きました。

非同期処理はよく使うと思うので、ちゃんとテストコード書いてあげましょう!