setoya-blog

システム開発技術、データ分析関連でお勉強したことや、山奥生活を綴る、テンション低めなブログです。

Objective-Cでの単体テスト(Unit Test)の実装方法

Xcodeに標準でテスト用のフレームワークがインストールされているので、それを使う。
アップルの公式iOS開発ガイド(PDF)にもやり方は記載されている。

  • ロジックテスト
  • アプリケーションテスト

の2つのテストのやり方があり、ロジックテストのほうがいわゆる単体テストで、実機の中で動作させないテストのこと。実機の中で動作させるテスト(たぶん、カメラとかデバイス依存部分のテストなどに使うんだと思う。)がアプリケーションテストだそうだ。

ロジックテストの方は、以下の流れですごく簡単に実装できる。

  1. テスト用のビルドターゲットを作成
  2. テストケースを作成し、ビルドターゲットに追加
  3. アクティブターゲットを1で作成したビルドターゲットに設定した後、ビルド

1. テスト用のビルドターゲットを作成

Xcodeのプロジェクトで、「ターゲット」を右クリックして、「Unit Test Bundle」を選択する。
f:id:sessan:20101218223548p:image
ちなみに、ターゲットはアプリケーションのビルド成果物のようなものであり、Javaでいうところのjarファイルのこと。Unit Test Bundleはテスト用のターゲットであり、アプリケーションの成果物として実態はたぶんないと思う。

2. テストケースを作成し、ビルドターゲットに追加

つぎに、テストケースを実装するクラスを作成する。
あらかじめ、「Tests」などのグループを作っておいて、そのグループにテスト用のクラスを配置していくのがよいと思う。
f:id:sessan:20101218223549p:image
ちなみに、追加するテスト用のクラスは、テスト用のターゲットに含めるようにし、実際に完成品となるアプリである別のターゲットには含めないようにする。
f:id:sessan:20101218223550p:image
デフォルトでは、以下のヘッダファイルができる。が、アプリを実機で動かしながらテストする必要がなく、単純ないわゆる単体テストをしたい場合は、冒頭のUSE_APPLICATION_UNIT_TESTは0にしておく。(最初ここにひっかかった。。自動生成されるテンプレートでは1になっている。)

SampleTest.h

#define USE_APPLICATION_UNIT_TEST 0

#import <SenTestingKit/SenTestingKit.h>
#import <UIKit/UIKit.h>
//#import "application_headers" as required


@interface SampleTest : SenTestCase {

}

#if USE_APPLICATION_UNIT_TEST
- (void) testAppDelegate;       // simple test on application
#else
- (void) testMath;              // simple standalone test
#endif

@end


テストケースの実装クラスは、デフォルトである程度テンプレートが作られ、以下のような感じになる。
ちなみに、さっきのUSE_APPLICATION_UNIT_TESTが1のままだと、#if USE_APPLICATION_UNIT_TESTの部分が有効になってしまい、testAppDelegateが実行され、かならず失敗する。

SampleTest.m

#import "SampleTest.h"


@implementation SampleTest

#if USE_APPLICATION_UNIT_TEST     // all code under test is in the iPhone Application

- (void) testAppDelegate {
    
    id yourApplicationDelegate = [[UIApplication sharedApplication] delegate];
    STAssertNotNil(yourApplicationDelegate, @"UIApplication failed to find the AppDelegate");
    
}

#else                           // all code under test must be linked into the Unit Test bundle

- (void) testMath {
    
//    STAssertTrue((1+1)==2, @"Compiler isn't feeling well today :-(" );
	STFail(@"Must fail to succeed!");
    
}


#endif


@end

3. アクティブターゲットを1で作成したビルドターゲットに設定した後、ビルド

あとは、アクティブターゲットを1で作成したビルドターゲットに設定して、ビルドを実行する。
1で作成したターゲットを右クリックして、ビルドでもよい。テストが失敗すると、ビルドエラーのような表示が出る。表示のされ方はJUnit風ではない感じ。普通にバグっぽい感じでテスト失敗が報告された。