2

KIF 就像魔术一样,最近让我很困惑。这就是 KIF 和 XCTest 的工作原理。

在 WWDC 2014 & 2013 中说过:测试代码作为插件注入到宿主应用程序中,那么主应用程序作为插件可以窃听哪些信息?主机应用程序插件之间的关系是什么?

使用 KIF,我们可以感知通知和 URL 请求,但它是如何工作的?我的第一个想法是主机应用程序中的所有上下文都与插件共享但是为什么在测试中,我们不能修改主应用程序中的变量?

例如:

我们有两个目标:

魔法计划

-- 魔法应用

-- MagicUITest <- KIFTest 目标

假设我有一个名为 MagicClass 的文件:

class MagicClass {
  static var a = 1
}

如果我想在 MagicUITest 中修改该变量,这可能吗?

我现在面临的问题是如何将不同的 UIViewController 注入到 RootViewController 中,以便我可以从每个单独的 ViewController 运行 KIF 测试,并且不需要一直经历登录过程。我的猜测是:

在魔术应用程序中:

class AppDelegate : .. , .. {
  func application(application: UIApplication, willFinishLaunchingWithOptions   launchOptions: [NSObject : AnyObject]?) -> Bool {
   if MagicClass.a == 1 {
      window.rootViewController = AViewController()
   } else {
      window.rootViewController = BViewController()
   }
  }
}

在 KIFTest 的 setUp() 中:

setUp() {
  Magic.a = 2
}

但不工作..

一件事是 Magic.a = 2 不会改变 MagicApp 中的 Magic.a,二是 application(..,..,..) 函数将在调用 setUp() 之前结束..

任何想法 ?

4

1 回答 1

3

虽然您是正确的,您尝试过的确切代码不起作用,但您将能够使用非常相似的方法。

例如,这段代码是直接从我正在开发的应用程序中抄录而来的,该类名为RootViewController(你猜对了)应用程序的根视图控制器:

public override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    if NSProcessInfo.processInfo().environment["TESTING"] == nil {
        loadChildren()
    }
}

它所做的是寻找一个环境变量来决定它是否应该自动继续加载应用程序,如果它找到了环境变量,它会等待测试堆栈完成设置并告诉它接下来要加载应用程序的哪个部分。(如果它是一个非常小的应用程序,您也可以在您的应用程序委托中执行此操作。)

您可以通过在 Xcode 中编辑方案来设置环境变量: 描述添加环境变量的屏幕截图

尽管如此:使用此策略时要小心。您希望您的测试能够测试您的应用程序中存在的功能,如果任意显示不同的屏幕是您的应用程序的一项功能,那可能没问题。但是,如果您开始编写使您的应用程序在测试时表现不同的代码,那么您就不再是真正地测试您的应用程序了,是吗?

于 2015-04-07T15:53:07.567 回答