Google Toolbox for Mac の iPhoneUnitTesting を使ってみた

ソフト開発に必須なUnitTestですが、Xcodeで動くUnitTest としてはiPhone Dev Center: iPhone Development Guide: Unit Testing Applications があります。このページに丁寧に使い方が書かれているので説明通りに設定する事で UnitTest が使えるようになります。ただし、この SenTestingKit にはいくつかの問題があります。

http://google-toolbox-for-mac.googlecode.com/svn/site/gtm.png

まずテストが結果がコンパイルエラーのように表示されるので、チェックするのがめんどうです。 そして、テストが通らなかった場合にデバックしようとしてもコンソール等にログを出したりできません ^^); この問題は致命的です。


そこで、他の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日修正)