I use the following technique to set values in my App before running UI tests. Useful for setting defaults or turning on networking mocks, etc. For the most part, I haven't needed to read anything out of the app yet. Everything is reflected in the UI and can be tested that way. Soon we're going to add tests to ensure the app makes certain network calls. I'm not yet sure how we'll test that from inside a UI test case.
Set arguments in your UI test
let app = XCUIApplication()
app.launchArguments = ["ResetDefaults", "NoAnimations", "UserHasRegistered"]
app.launch()
Read arguments in your app
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
var arguments = NSProcessInfo.processInfo().arguments
arguments.removeFirst()
print("App launching with the following arguments: (arguments)")
// Always clear the defaults first
if arguments.contains("ResetDefaults") {
destroyUserDefaults()
clearKeychain()
}
for argument in arguments {
switch argument {
case "NoAnimations":
UIView.setAnimationsEnabled(false)
case "UserHasRegistered":
Defaults.userRegistered = true
default:
break
}
}
}
Additional bonus: If you use launch arguments to configure your app, it's trivial to add flags to your Xcode scheme. For example, I have a scheme that clears all stored data, and stubs out any login attempt with a success response. I can now "login" via the simulator without hitting any servers.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…