UI Testing Mocking Data Xcode 7

Hello,


I am trying to introduce mock data inside of the UI Test with the new Xcode 7. However I haven't seen any kind of documentation about it.


Does someone know anything more?


Thanks

Replies

I started to reply here, but it was turning into a full blog post, so I did a blog post:


http://www.sunetos.com/items/2015/07/20/mocking-url-request-with-xcode-7-ui-testing/

There are a few steps.

1) set some sort of flag in the XCUIApplication Launch Arguments during the test setup so you can detect inside the application when you are in a test environment.


2) Inside application:didFinishLoadingWIthOptions: you can add code that looks like this:

        let arguments = NSProcessInfo.processInfo().arguments
        let mock = arguments.contains("MOCKFLAG")
        if ( mock ) {
              //add code here to hijack your data stream
        }


3) If your data stream is http based (rest services) you can use something like OHHTTPStubs to hijack the HTTP service calls and dummy up responses to them. This is working well for me. You can even dummy up failure responses which makes full system testing quite easy. I build an HttpHijack class which contains a small in-memory model and manipulates it from the hijacked methods. The app behaves in all ways like it is making REST calls to an external server (the app code itself is unmodified).


4) If your data stream is an embedded database you would probably want to design your data-access layer to be redirectable, and use the "mock" detection to redirect to an internal database with faked data inside.


You would likely want to keep the faked data sources to be internal to your app since most of the time relying on UI Tests to access resources on web servers is sketchy at best.

We develop a library, SBTUITestTunnel, that should help you out. See my answer here: https://forums.developer.apple.com/message/94761

This is incorrect. As RaviDesai describes, you can indeed pass information into the application for different UI testing conditions. The key is that you have to change how you create the application in your UI test.


Continuing on RaviDesai's example, you'd want your setUp routine in each UI test to look something like:


override func setUp() {
    super.setUp()

    continueAfterFailure = false
       
    let app = XCUIApplication()
       
    app.launchArguments.append("MOCKFLAG")
       
    app.launch()
}


By changing what launch argument you pass for which set of tests, you can control how the app behaves. When I need to change this value, I create a new UI test file, change the launch arguments for what that test needs, then only add tests to that file that use this particular argument. I've found this a very effective way for handle situations like simulating no internet access or making a network request fail "on demand".


Glen

And you are absolutelly right! I have just logged in to delete my comment, because I realized it's wrong.