【问题标题】:Mocking objects with Xcode 7 UI Automation使用 Xcode 7 UI 自动化模拟对象
【发布时间】:2016-01-20 21:38:09
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: ios xcode unit-testing xcode7 kif


    【解决方案1】:

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

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

    这样做的缺点是模拟代码并未严格包含在测试包中,并且您最终会在您的应用程序中使用该代码(除非您使用 #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 测试不依赖于服务器响应(毕竟其他事情是测试服务器)。

    【讨论】:

    • 哇哦!这打破了整个依赖注入的想法。我绝对不想在我的生产代码中引入测试代码。这真的是一场精彩的表演。
    • @user1366265 我同意,尽管如果您将所有内容都包装在我上面提到的编译器指令中,您在技术上不会将此类代码引入您的生产二进制文件(假设您的编译器标志设置正确)。话虽如此,显然不理想且容易出错。
    猜你喜欢
    • 2016-01-05
    • 2015-12-27
    • 2017-03-24
    • 1970-01-01
    • 2016-05-20
    • 2016-01-18
    • 2023-03-18
    • 1970-01-01
    • 2017-01-28
    相关资源
    最近更新 更多