简体   繁体   English

使用Xcode 7 UI Automation模拟对象

[英]Mocking objects with Xcode 7 UI Automation

I was using KIF Framework until now for iOS UI Automation. 到目前为止,我正在使用KIF Framework进行iOS UI自动化。 KIF (also Unit Test) targets runs the Unit/UI testing code in the same process as your application is running and we can easily Mock different objects/classes used by the app to show mock data. KIF(也是单元测试)目标在与应用程序运行相同的过程中运行单元/ UI测试代码,我们可以轻松模拟应用程序使用的不同对象/类来显示模拟数据。

When switching to Xcode 7 based new UI Automation, I found that UI Unit Test target runs in separate process and it launches the application in separate process. 当切换到基于Xcode 7的新UI自动化时,我发现UI单元测试目标在单独的进程中运行,并且它在单独的进程中启动应用程序。 And thus it's not possible to access App classes/objects through unit tests and mock them. 因此,无法通过单元测试访问App类/对象并模拟它们。

Did anyone faced the same issue, and know about any workaround? 有没有人面临同样的问题,并了解任何解决方法?

Please let me know if any more details are needed. 如果需要更多细节,请告诉我。

Answer: Please see the detailed answer below. 答:请参阅下面的详细答案。 Also here is link to reply from Apple devs: https://forums.developer.apple.com/thread/23552 此处还有来自Apple开发者的回复链接: https//forums.developer.apple.com/thread/23552

Because you are running in a different process, there isn't really a way to inject mocks into your application via your tests. 因为您在不同的进程中运行,所以没有办法通过测试将mocks注入您的应用程序。 Having said that, you do get to control your App's process, and can thus have some effects on it. 话虽如此,您确实可以控制应用程序的进程,因此可以对其产生一些影响。

I've gone back and forth on how I feel about this (I'm currently undecided), but you could add some code to your app that reads an environment variable (via NSProcessInfo ) that makes the app behave differently (ie, change out what your dependency injection is injecting into your class so it uses mocks). 我已经来回了解我对此的NSProcessInfo (我目前还未定),但您可以在应用中添加一些代码来读取环境变量(通过NSProcessInfo ),使应用程序的行为不同(即更改)你的依赖注入注入你的类,所以它使用模拟)。

The downside to this is the mock code isn't contained strictly in the test bundle, and you end up with that code in your app (unless you use #if statements to isolate it). 这样做的缺点是模拟代码没有严格包含在测试包中,并且您最终会在应用程序中使用该代码(除非您使用#if语句来隔离它)。 Obviously it's also important to be prudent with your code branching, so you don't invalidate your testing. 显然,谨慎处理代码分支也很重要,因此不要使测试无效。

You could setup an environmental variable prior to launching the app in your UI test: 您可以在UI测试中启动应用程序之前设置环境变量:

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

Then in your application you can check for that, possibly in a #if statement and alter your behavior: 然后在您的应用程序中,您可以检查它,可能在#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

I've been considering this approach for implementing a mock service layer that just replays some canned server responses so I can make my UI tests not depend on server responses (other things test the server, after all). 我一直在考虑这种方法来实现一个模拟服务层,它只是重放一些罐装服务器响应,所以我可以让我的UI测试不依赖于服务器响应(毕竟其他东西测试服务器)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM