Apple Developer Connection にXCodeを使った単体テストの方法が書かれていたので、備忘録を残そうと思ったのだけれども、大はまりしました。でも、なんとか自力解決しました。
ほとんど情報がないのだけれども、みんなどうやってるの?
準備 †
- テスト対象のアプリケーションのプロジェクトを作成する。ここではプロジェクトの名前をCalculatorということにする。
- アプリケーションに単体テスト用のターゲット(CalculatorTest)を追加する
- ProjectメニューのAdd new target …を使い、雛形としてUnit Test Bundleを選び、適切な名前で保存。
- Target Infoウィンドウでテスト対象のアプリケーションを参照するように設定する。
- BuildタブでOther Linker FlagsのなかのCocoaをFoundationに置換し、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 は開発者用の場所に保存されています。標準的なパスから開発者向けの場所にリンクを張れば、読み込んでくれるだろうと期待したのです。
うまくいきましたよ!!(たぶん、もっと正しい方法があるはずなのですが。。。)
参考文献 †
- Test Driven Development in XCode XCode を使ったTDDについて解説しています。TDDの参考になりますよ。
- Test driving your code with OCUnit ご本家の情報ですが、ここには救われませんでした。
- XCode unit testing guide こちらはさらに詳しい解説なのですが、ぼくの悩みには応えてくれませんでした。でも、テストの方法については参考になります。
- [[]]
-
Wroxから出版されている「Professional XCode 3」James Bucanek著に詳しい手順が載っていますよ.


2個のコメント
この投稿記事に対するコメントのフィード
トラック・バックのリンク: http://ken-wakita.net/ja/2010/01/unit-testing-in-xcode/trackback/