Google Toolbox for Mac の iPhoneUnitTesting を使ってみた
ソフト開発に必須なUnitTestですが、Xcodeで動くUnitTest としてはiPhone Dev Center: iPhone Development Guide: Unit Testing Applications があります。このページに丁寧に使い方が書かれているので説明通りに設定する事で UnitTest が使えるようになります。ただし、この SenTestingKit にはいくつかの問題があります。
まずテストが結果がコンパイルエラーのように表示されるので、チェックするのがめんどうです。 そして、テストが通らなかった場合にデバックしようとしてもコンソール等にログを出したりできません ^^); この問題は致命的です。
そこで、他のUnitTestツールを探したところGoogle Toolbox for Mac の iPhoneUnitTesting というものがありました。これは UnitTest用のiPhoneアプリを作り iPhoneシミュレータで実行し以下のようにコンソールにテスト結果を表示してくれます。
したがって、NSLogでログを書いたりする事で、バグ調査が出来ます。
[Session started at 2009-12-27 10:20:08 +0900.] .... Test Suite 'PlaceListTests' started at 2009-12-27 10:20:14 +0900 Test Case '-[PlaceListTests testAddPlace]' passed (0.000 seconds). Test Case '-[PlaceListTests testAddPlaceList]' passed (0.000 seconds). Test Case '-[PlaceListTests testSortByDistanceFromLongitude]' passed (0.000 seconds). Test Case '-[PlaceListTests testToSTringArrayAndFromStringArray]' passed (0.000 seconds). Test Suite 'PlaceListTests' finished at 2009-12-27 10:20:14 +0900. Executed 4 tests, with 0 failures (0 unexpected) in 0.001 (0.001) seconds Test Suite '/Users/yy/Library/Application Support/iPhone Simulator/User/Applications/FE731758-1E16-4BF7-9BDD-1E117626416F/UnitTests.app' finished at 2009-12-27 10:20:14 +0900. Executed 6 tests, with 0 failures (0 unexpected) in 0.036 (0.036) seconds
使い方は、上のリンクページに書かれていますが、そのままでは上手く行かなかったので以下のようにしました。
iPhoneUnitTestingコードのコピー
下の画像のように、GTMPIphoneUnitTestというグループとフォルダーを作り必要なiPhoneUnitTesting のコードをコピーしました。リンクページには書かれていませんでしたが、GTMObjC2Runtime.h , GTMObjC2Runtime.m も必要でした。
UnitTest用ターゲットの作成
下の画像のように UnitTest用ターゲット を作成し、上で作った GTMPIphoneUnitTestグループやテストに必要なソース、Framework(ライブラリー)を追加します。
SenTestingKit と併用する場合には、UnitTest実行用 shell scriptの設定
SenTestingKit と iPhoneUnitTesting の両方を走らせたい場合のみ以下の設定を行います。(1/19日修正)
UnitTest用 ターゲットに 追加→新規ビルドフェーズ→新規スクリプト で UnitTest実行用 shell scriptの設定を設定します。 shell script は "${SRCROOT}/GTMIPhoneUnitTest/RunIPhoneUnitTest.sh"
UnitTestのコードを書く
適当なグループ(とフォルダー)を作り、そこにUnitTestのコードを書きます。
例)
// PlaceListTests.h #import "GTMSenTestCase.h" #import "PlaceList.h" @interface PlaceListTests : GTMTestCase { } @end
// PlaceListTests.m #import "PlaceListTests.h" @implementation PlaceListTests - (void) testAddPlace { PlaceList *list = [PlaceList placeList]; [list addPlace:[Place placeWithLongitude:138.658664 latitude:35.567224 name:@"自由が丘"]]; STAssertEquals(1, [list count], @"add後countが増えている"); STAssertEquals((float)138.658664, [list longitudeAtIndex:0], @"緯度が取得できる"); STAssertEquals((float)35.567224, [list latitudeAtIndex:0], @"経度が取得できる"); STAssertEquals(@"自由が丘", [list nameAtIndex:0], @"名前が取得できる"); } ... @end
UnitTestの実行
ターゲットを UnitTestsに切り換え ビルトと実行 を行うと、まず SenTestingKit のUnitTestが行われ (?) エラーがなければ、 iPhoneシミュレータ上で UnitTestが実行されます。(1/19日修正)
SenTestingKit でエラーがUnitTestが不成功になった場合は、そのテストをコメントアウトし、iPhoneシミュレータ上で UnitTestが通るようにして、NSLog等で原因追及と対処を行いながらテストを進めて行けます。
最初に走る SenTestingKit は要らないのですが・・・・設定できるのかな!?(1/19日修正)