TDDに限らず単体テストを動作させたら早めに結果が欲しいでしょう。
ios開発では、何も考えずに書くとAppDelegateが呼ばれて、Controllerが呼ばれて・・・となり、時間が無駄にかかったり、テストケースが動く前に落ちたりします。
知っている人にとっては当たり前の解決方法ですが、意外と日本語記事が少なかったので、後輩のために書いてます。
Main Interfaceをコードで書く
以下の部分を書いているとテストを動作させるとそこのControllerが動くので消しておきます。
上記の代わりにコードで書いときます。
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let window = UIWindow(frame: UIScreen.main.bounds)
self.window = window
let storyboard = UIStoryboard(name: "Main", bundle: nil)
window.rootViewController = storyboard.instantiateInitialViewController()
window.makeKeyAndVisible()
return true
}
main関数を作成
まずは、自分のmain関数を動作させたいので、AppDelegateクラスの @UIApplicationMain
を削除しておきます。
-@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
次に、以下のファイルを作成します。
main.swift
let appDelegateClass: AnyClass? =
NSClassFromString("テストターゲット名.TestingAppDelegate") ?? AppDelegate.self
let args = UnsafeMutableRawPointer(CommandLine.unsafeArgv).bindMemory(to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc))
UIApplicationMain(CommandLine.argc, args, nil, NSStringFromClass(appDelegateClass!))
Objective-Cでは以下です。
main.m
int main(int argc, char *argv[]) {
@autoreleasepool {
Class appDelegateClass = NSClassFromString(@"TestingAppDelegate");
if (!appDelegateClass) {
appDelegateClass = [AppDelegate class];
}
return UIApplicationMain(argc, argv, nil, NSStringFromClass(appDelegateClass));
}
}
テスト用のAppDelegateを作成
以下のファイルをテストターゲットに置きます。
TestingAppDelegate.swift
class TestingAppDelegate: NSObject {
var window: UIWindow?
}
Objective-Cでは以下です。
TestingAppDelegate.h
@interface TestingAppDelegate : NSObject
@property(nonatomic, strong) UIWindow *window;
@end
TestingAppDelegate.m
@implementation TestingAppDelegate
@end
以上です。