Apple Developer Connection にXCodeを使った単体テストの方法が書かれていたので、備忘録を残そうと思ったのだけれども、大はまりしました。でも、なんとか自力解決しました。
ほとんど情報がないのだけれども、みんなどうやってるの?
#contents
* 準備
+ テスト対象のアプリケーションのプロジェクトを作成する。ここではプロジェクトの名前をCalculatorということにする。
+ アプリケーションに単体テスト用のターゲット(CalculatorTest)を追加する
++ ”Project”メニューの”Add new target …”を使い、雛形として”Unit Test Bundle”を選び、適切な名前で保存。
++ ”Target Info”ウィンドウでテスト対象のアプリケーションを参照するように設定する。
++ ”Build”タブで”Other Linker Flags”のなかの”Cocoa”を”Foundation”に置換し、”GCC_PREFIX_HEADER” の設定を削除する。
*テストケースの作成
”Active Target”をCalculatorTestにし、それにテストケースを書くためのファイルを追加します。普通に作成するとヘッダが自動作成されますが、邪魔なので作成しないのがコツだそうです。テストケースは以下のような感じで書きます。ヘッダがないので、インタフェイス宣言を書くのを忘れないで下さい。
#include
#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
@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:http://blog.jayway.com/2010/01/15/test-driven-development-in-xcode/%5D%5D XCode を使ったTDDについて解説しています。TDDの参考になりますよ。
– [[Test driving your code with OCUnit:http://developer.apple.com/tools/unittest.html%5D%5D ご本家の情報ですが、ここには救われませんでした。
– [[XCode unit testing guide:http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/UnitTesting/0-Introduction/introduction.html%5D%5D こちらはさらに詳しい解説なのですが、ぼくの悩みには応えてくれませんでした。でも、テストの方法については参考になります。
– [[]]
Wroxから出版されている「Professional XCode 3」James Bucanek著に詳しい手順が載っていますよ.
貴重な情報をありがとうございました!見てみます。