XCode での単体テスト

Apple Developer Connection にXCodeを使った単体テストの方法が書かれていたので、備忘録を残そうと思ったのだけれども、大はまりしました。でも、なんとか自力解決しました。

ほとんど情報がないのだけれども、みんなどうやってるの?

準備

  1. テスト対象のアプリケーションのプロジェクトを作成する。ここではプロジェクトの名前をCalculatorということにする。
  2. アプリケーションに単体テスト用のターゲット(CalculatorTest)を追加する
    1. ProjectメニューのAdd new target …を使い、雛形としてUnit Test Bundleを選び、適切な名前で保存。
    2. Target Infoウィンドウでテスト対象のアプリケーションを参照するように設定する。
    3. BuildタブでOther Linker FlagsのなかのCocoaFoundationに置換し、GCC_PREFIX_HEADER の設定を削除する。

テストケースの作成

Active TargetをCalculatorTestにし、それにテストケースを書くためのファイルを追加します。普通に作成するとヘッダが自動作成されますが、邪魔なので作成しないのがコツだそうです。テストケースは以下のような感じで書きます。ヘッダがないので、インタフェイス宣言を書くのを忘れないで下さい。

#include <SenTestingKit/SenTestingKit.h>
#include "Calculator.h"

@interface CalculatorTest : SenTestCase {
	Calculator* calculator;
}
@end

@implementation CalculatorTest

-(void) setUp {
	calculator = [[Calculator alloc] init];
}

-(void) tearDown {
	[calculator release];
}

-(void)testAdd {
	int expected = 11;
	int result = [calculator add:5 to:6];
	STAssertEquals(expected, result,
				   @"We expected %d, but it was %d", expected, result);
}

-(void)testDivide {
	float expected = 2.5;
	float result = [calculator divide: 5 by: 2];
	STAssertEquals(expected, result,
				   @"We expected %f, but it was %f", expected, result);
}

-(void)testDivideByZero {
	STAssertThrows([calculator divide:5 by:0],
				   @"We expected an exception to be raised when dividing by 0");
}
@end

テストの実行

Build and Runすると当然のことながら、Calculator.[h|m]がないので、コケます。これらのファイルをプロジェクトに追加しましょう。今度は、アプリケーション本体のCalculatorターゲットとテスト用のCalculatorTestターゲットの両方に追加します。

まずはヘッダファイル (Calculator.h)

#import <Cocoa/Cocoa.h>

@interface Calculator : NSObject {
}

-(int)add:(int)a to:(int)b;
-(float)divide:(int)a by:(int)b;

@end

そして、こちらが本体 (Calculator.m)

#import "Calculator.h"

@implementation Calculator

-(int)add:(int)a to:(int)b {
	return a + b;
}

-(float)divide:(int)a by:(int)b {
	float result = (float)a/b;
	if (result == INFINITY) {
		[NSException raise:@"Cannot divide by zero!"
					format:@"Not possible to divide %d with %d", a, b];
	}
	return result;
}

@end

ここで Build and Run すればテストが通ります。

落とし穴

というのが、あるべき姿なのですが、ぼくがやってみたところ以下のようなエラーメッセージが出ました。どうもSenTestingKitフレームワークの参照関係がおかしいようです。

SenTestingKit/SenTestingKit.h: No such file or directory
cannot find interface declaration for 'SenTestCase', superclass of '***'

で、Google 先生にいろんなことを尋ねて、いろいろ学んだのですが決め手は見つかりませんでした。最後に自分の運を信じて以下をやりました。

sudo ln -s /Developer/Library/Frameworks/SenTestCase.framework /System/Library/Frameworks

/System/Library/Frameworks は標準的なフレームワークが保存されている場所で、SenTestCase.framework は開発者用の場所に保存されています。標準的なパスから開発者向けの場所にリンクを張れば、読み込んでくれるだろうと期待したのです。

うまくいきましたよ!!(たぶん、もっと正しい方法があるはずなのですが。。。)

参考文献


  1. JamiePapa’s avatar

    Wroxから出版されている「Professional XCode 3」James Bucanek著に詳しい手順が載っていますよ.

    返信

    1. ken’s avatar

      貴重な情報をありがとうございました!見てみます。

      返信

Spam Protection by WP-SpamFree