iOS Swift:为XCTest分离AppDelegate

问题描述 投票:14回答:3

由于一些问题,我希望项目中的XCTest目标能够运行单独的应用程序委托。使用ObjC,这是一个相对简单的过程:操纵main.m(参见:https://stackoverflow.com/a/15725328/1299041)。

由于似乎在AppDelegate中使用@UIApplicationMain初始化Swift应用程序,是否可以使用单独的AppDelegate为测试目标进行初始化?

ios swift xctest
3个回答
13
投票

强烈建议在正常的代码检查中添加条件是否正在测试。相反,你应该在测试中嘲笑你的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"]

2
投票

对此的解决方案如下:

  1. 复制现有应用程序的Target并将其重命名为适当的名称。在你的情况下可能是'TestingHarness'或其他一些。请注意,您还需要更改包标识符并重命名相应的Info.plist文件。重命名Info.plist文件意味着您需要更改新目标的Build Settings选项卡中的Info.plist文件名设置以匹配新名称。
  2. 创建另一个*AppDelegate.swift文件。在你的情况下,我称之为TestAppDelegate.swift
  3. 将现有的AppDelegate.swift文件内容复制到TestAppDelegate.swift并根据需要进行编辑。确保留下@UIApplicationMain注释并实现所需的UIApplicationDelegate回调。
  4. 更改每个*AppDelegate.swift文件的目标成员身份,以便AppDelegate.swift不包含在您的新“TestHarness”目标中,并且TestAppDelegate.swift不包含在主应用程序的目标中。 (您可以在文件浏览器中选择文件的目标成员资格并打开文件检查器,默认情况下可以在右侧栏中访问,或者在“查看” - >“实用程序”下的菜单中选择它。)
  5. 现在,您有两个单独的目标,这些目标具有可以独立构建和运行的单独的App Delegates。最后一步是选择新的“TestHarness”目标作为测试目标的主机应用程序。 (单击文件浏览器中的顶级项目条目,然后在子列表中单击所需的测试目标。在常规选项卡上,您将看到主机应用程序是唯一可用的下拉列表。)

注意:这些说明适用于Xcode 7.2。


0
投票

要实现这一点,Swift需要采取以下几个步骤:

  1. 如果您使用的是Storyboard,请在AppDelegate上以编程方式创建视图堆栈。 从项目配置Project configuration中删除Main.storyboard 从AppDelegate的开头删除@UIApplicationMain并添加此代码。 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 }
  2. 在目标的根目录下创建一个新文件,并将其命名为main.swift。 如果您不需要为测试进行任何设置,请添加此代码 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)
© www.soinside.com 2019 - 2024. All rights reserved.