使用 Xcode 7 UI 自动化模拟对象

Mocking objects with Xcode 7 UI Automation

到目前为止,我一直在使用 KIF Framework iOS UI 自动化。 KIF(也是单元测试)目标在与您的应用程序 运行 相同的进程中运行 Unit/UI 测试代码,我们可以轻松模拟应用程序使用的不同 objects/classes 来显示模拟数据。

切换到基于 Xcode 7 的新 UI 自动化时,我发现 UI 单元测试目标在单独的进程中运行,并在单独的进程中启动应用程序。因此无法通过单元测试访问 App classes/objects 并模拟它们。

有没有人遇到同样的问题,并且知道任何解决方法?

如果需要更多详细信息,请告诉我。

答:请看下面的详细答案。这里还有 link 苹果开发者的回复:https://forums.developer.apple.com/thread/23552

因为您 运行 在不同的进程中,所以实际上没有办法通过测试将模拟注入到您的应用程序中。话虽如此,您确实可以控制应用程序的进程,因此可以对其产生一些影响。

我已经反复讨论了我对此的看法(我目前尚未决定),但是您可以向您的应用程序添加一些代码来读取一个环境变量(通过 NSProcessInfo),这使得该应用程序的行为有所不同(即,更改您的依赖注入注入到您的 class 中的内容,因此它使用模拟)。

这样做的缺点是模拟代码并未严格包含在测试包中,您最终会在应用程序中使用该代码(除非您使用 #if 语句将其隔离)。显然,谨慎使用代码分支也很重要,这样您就不会使测试无效。

您可以在 UI 测试中启动应用程序之前设置环境变量:

let app = XCUIApplication()
app.launchEnvironment = ["UITestUseMocks" : "true"]
app.launch()

然后在您的应用程序中,您可以检查它,可能在 #if 语句中并改变您的行为:

#if TEST_TARGET
    if let useMocks = NSProcessInfo().environment["UITestUseMocks"] where useMocks == "true" {
        // Alter services used in dependency injection or some other testing behavior
    }
#endif

我一直在考虑用这种方法来实现一个模拟服务层,它只重播一些固定的服务器响应,这样我就可以让我的 UI 测试不依赖于服务器响应(毕竟其他东西测试服务器).