Hatena::Groupiphone-dev

haoyayoi Dev Style このページをアンテナに追加 RSSフィード

2012-04-17

cocos2dでSenTestingKitをつかったUnitTestを行う場合の注意点とか

| 13:16 | cocos2dでSenTestingKitをつかったUnitTestを行う場合の注意点とか - haoyayoi Dev Style を含むブックマーク はてなブックマーク - cocos2dでSenTestingKitをつかったUnitTestを行う場合の注意点とか - haoyayoi Dev Style cocos2dでSenTestingKitをつかったUnitTestを行う場合の注意点とか - haoyayoi Dev Style のブックマークコメント

誰かがもう本に書いてしまっていそうな内容ですが、気にしない。

cocos2dのprojectをSenTestingKitを使った自動テストに掛けた場合、テスト以前の想定外のエラー等が発生するケースがあります。それらのケース全てに対応できるかどうかは不明ですが、ある程度のカバーは可能になるであろうと思われる手順を以下に。

Build用に追加設定を行う

UnitTestを行う場合、ProjectのTargetに「Add Target」から「Cocoa Touch Unit Testing bundle」を指定するわけですが、これだけでは正常にテストできません。

  1. 追加したTargetのBuild Phaseから、「Compile Sources」にcocos2dのライブラリ(.mと.c)を一通りと、開発しているアプリのソース(.m)を一通り追加します。
  2. Build Settingsから、「Other Linker Flags」に「-lz」と入れます。
  3. Build Phaseの 「Link Binary With Libraries」に以下を追加します。(開発しているアプリの同じ構成+SenTestingKit)
    • AudioToolBox.framework
    • AVFoundation.framework
    • QuartzCore.framework
    • OpenAL.framework
    • OpenGLES.framework
    • CoreGraphics.framework
    • SenTestingKit.framework
    • UIKit.framework
    • Foundation.framework

基本は、開発しているTargetと同じ構成にします。

Test時にGL_VENDOR等がnullにならないようにする

test時にwindowを生成していないことが原因です。ccMacros.h にある CC_DIRECTOR_INIT() を呼び出します。

#import <SenTestingKit/SenTestingKit.h>
#import "ccMacros.h"

@interface GOKTBase : SenTestCase
{
     UIWindow *window;
}
@end

@implementation TestBase

- (void)setUp
{
    [super setUp];
    CC_DIRECTOR_INIT();
}

- (void)tearDown
{
    CC_DIRECTOR_END();
    [super tearDown];
}

@end

テスト用に上記のような内容のベースクラスをはさんでしまうのも手です。

これで、テスト自体はコケることなく実行されるようになります。

cocos2dの一部ソースコードをTest Targetでも問題なく動くように修正する

CCSpriteなどを使ったファイルにて、CCTextureCacheにイメージを追加しようとして失敗するケースがあります。これは、Main BundleのパスがアプリとUnitTestで異なることをcocos2d側では考慮されていない為です。(参考:OCUnit & NSBundle

  • CCFileUtils.m
+(NSString*) fullPathFromRelativePath:(NSString*)relPath resolutionType:(ccResolutionType*)resolutionType
{
	NSAssert(relPath != nil, @"CCFileUtils: Invalid path");
	
	NSString *fullpath = nil;
	
	// only if it is not an absolute path
	if( ! [relPath isAbsolutePath] ) {

		// pathForResource also searches in .lproj directories. issue #1230
		NSString *file = [relPath lastPathComponent];
		NSString *imageDirectory = [relPath stringByDeletingLastPathComponent];
-              fullpath = [[NSBundle mainBundle] pathForResource:file     
+		fullpath = [[NSBundle bundleForClass:[CCFileUtils class]] pathForResource:file
												   ofType:nil
											  inDirectory:imageDirectory];

		
	}

これでCCTextureCacheで問題が発生することはなくなります。