56
48

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-08-04

#はじめに
今回は、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で非同期処理のテストをする方法を書きました
非同期処理はよく使うと思うのでちゃんとテストコード書いてあげましょう!
56
48
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
56
48

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?