由于一些问题,我希望项目中的XCTest目标能够运行单独的应用程序委托。使用ObjC,这是一个相对简单的过程:操纵main.m
(参见:https://stackoverflow.com/a/15725328/1299041)。
由于似乎在AppDelegate中使用@UIApplicationMain
初始化Swift应用程序,是否可以使用单独的AppDelegate为测试目标进行初始化?
强烈建议在正常的代码检查中添加条件是否正在测试。相反,你应该在测试中嘲笑你的AppDelegate
做任何你想做的事情。
然后你可以替换UIApplication的委托是setUp
在你的每个XCTestCase
'es的超级类。
class MockAppDelegate:NSObject, UIApplicationDelegate {
}
class BaseTest: XCTestCase {
override func setUp() {
super.setUp()
UIApplication.shared.delegate = MockAppDelegate()
}
}
class Test1: BaseTest {
override func setUp() {
super.setUp()
// normal testing
}
}
如果您仍想停止测试的代码执行,这是我的方法很好:
您可以向app添加启动参数,表明这是测试运行
这些参数可从NSUserDefaults
访问
#define IS_TESTS [[NSUserDefaults standardUserDefaults] boolForKey:@"TESTING"]
对此的解决方案如下:
*AppDelegate.swift
文件。在你的情况下,我称之为TestAppDelegate.swift
。AppDelegate.swift
文件内容复制到TestAppDelegate.swift
并根据需要进行编辑。确保留下@UIApplicationMain
注释并实现所需的UIApplicationDelegate
回调。*AppDelegate.swift
文件的目标成员身份,以便AppDelegate.swift
不包含在您的新“TestHarness”目标中,并且TestAppDelegate.swift
不包含在主应用程序的目标中。 (您可以在文件浏览器中选择文件的目标成员资格并打开文件检查器,默认情况下可以在右侧栏中访问,或者在“查看” - >“实用程序”下的菜单中选择它。)注意:这些说明适用于Xcode 7.2。
要实现这一点,Swift需要采取以下几个步骤:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateInitialViewController()
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = vc
window.makeKeyAndVisible()
self.window = window
return true
}
import UIKit
let kIsRunningTests = NSClassFromString("XCTestCase") != nil
let kAppDelegateClass = kIsRunningTests ? nil : NSStringFromClass(AppDelegate.self)
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, kAppDelegateClass)
如果您需要在运行测试之前进行一些配置,请从NSObject创建一个新类FakeAppDelegate作为子类,并在那里添加您的设置代码。
将此代码放在main.swift中
import UIKit
let kIsRunningTests = NSClassFromString("XCTestCase") != nil
let kAppDelegateClass = kIsRunningTests ? NSStringFromClass(FakeAppDelegate.self) : NSStringFromClass(AppDelegate.self)
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, kAppDelegateClass)