Amazon

2015年1月5日月曜日

swiftのunit testでハマる

ユニットテストのようにパフォーマンスをテストするんだ!を参考にswiftの単体テストを書いてみました。
テストケースから対象のクラスにアクセスできずに2時間ほど費やしましたが下記で解決しました。
publicしかテストできないのは、どうかと思うのですが、swiftのテストフレームワークはXCTestより良いものがあるのかもしれません。

  • テストクラスのimportでプロジェクトを指定する。
  • テスト対象のクラスはpublicで定義する
  • テスト対象のクラスにpublic init() {} を定義する
  • テスト対象のfuncもpublicにする
  • xcodeでクリーンビルドする

記事の通りにLoggerクラスを追加して、テストケースを追加するとLoggerクラス定義のところで、"Use of unresolved identifier 'Logger'"エラーが出ました。

色々と調べてコードを変更してビルドしてもエラーメッセージは変わらず...
途中でxcodeは、ソース修正→保存ではビルドしないことに気が付きました。(何か設定あるのかもしれませんが...)

Command-bでビルドするようにしたところ、
テストクラスの先頭に"import プロジェクト名"を追加してテスト対象のクラスをpublic宣言するとエラーメッセージが"'Logger' cannot be constructed because it has no accessible initializers"になり、クラスにアクセスできるようになりました。

コンストラクタを追加すると"'Logger' does not have a member named 'XX'"に変わり、関数をpublic宣言するとエラーがなくなり実行出来ました。

記事通り、パフォーマンス測定の結果を見ることが出来ました。

今回使ったソースです。
xcodeでは、Command-sではなくCommand-bでソースを保存しよう。
Logger.swift
import Foundation

public class Logger
{
    let max = 10

    public init() {}
    
    public func writeNSLog() {
        for var i=0; i < max; i++ {
            NSLog("%d", i)
        }
    }
    
    public func writePrintln() {
        for var i=0; i < max; i++ {
            println(String(i))
        }
    }

}
LoggerTests.swift
import XCTest
import helloworld

class LoggerTests: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }
    
    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // This is an example of a functional test case.
        XCTAssert(true, "Pass")
    }

    func testPerformanceExample() {
        // This is an example of a performance test case.
        self.measureBlock() {
            // Put the code you want to measure the time of here.
        }
    }

    func testLoggerPrintln() {
        var logger = Logger()
        self.measureBlock() {
            logger.writePrintln()
        }
    }

    func testLoggerNSLog() {
        let logger = Logger()
        self.measureBlock() {
            logger.writeNSLog()
        }
    }
}

0 件のコメント: