Zhou Haibo
Zhou Haibo

Reputation: 2068

Is there a way to disable iOS simulator's network during a UI automation test

I get many tests, which require no network state. Because all the tests will executed in CI so cannot use a real device.

Solutions I found from internet:

  1. There is tool could be installed in Mac and control network status -> Cannot use for an automation test.
  2. Use real device -> No, because all tests would be executed in CI and also include parallel, so simulator is better way.

After these failed attempts, I inject "noNetwork" as environment to the app like this minimum example. And return a "noNetwork" Error to API calls if this env exist in code.

// In test
envs["networkStatus"] = "noNetworkConnection"
launchEnvironment = envs

// In app code
if ProcessInfo.processInfo.environment["networkStatus"] == "noNetworkConnection" {
            completion(.failure(.noNetworkConnection))
        }

It block the Simulator's network but another problem is coming, because launchEnvironment takes effect when app is launched, and there is API calls during app launch, so these API calls also get blocked as no network.

My purpose is to reach to a certain step then disable the network. I'm wondering whether there is a way to inject the env or what ever to the app during a UI test? Appreciate for any help, guys.

Upvotes: 1

Views: 1993

Answers (1)

Zhou Haibo
Zhou Haibo

Reputation: 2068

I find a way out, yesterday I totally re-consider how UI test interact with App, and the answer is UI interaction like button touch, pull to refresh, page opening, basically a user's action.

Thus, I create another global variable shouldDisableNetwork to control network connection together with injected env.

To do it, change this flag to true in some action code like button tap.

onSendButtonCompletion { [unowned self] in
    // For UI Test
    var shouldDisableNetwork = true
    ...
}

And now with two flags, when the button is tapped, shouldDisableNetwork become to true, then the network is disabled.

// In network call
        if ProcessInfo.processInfo.environment["networkStatus"] == "noNetworkConnection" && shouldDisableNetwork {
            completion(.failure(.noNetworkConnection))
            return
        }

It is ok for a simple test, though one thing worth to mention that this is one way trip, no turn back, but I could set shouldDisableNetwork to false in some other UI action, which one doesn't require network connection.

Upvotes: 1

Related Questions