Hey, there are a few options to achieve this, though all would require some minor changes to your app.
1) Using XCUIApplication.launchEnvironment
// ScreenAUITests.swift
func testSomeFeature() {
// launchEnvironment is a [String: String]
// anything added here can be retrieved within the app being tested
let app = XCUIApplication()
app.launchEnvironment = ["screenToLaunch": "screenA"] // you can clean this up by using enums to define the keys
app.launch()
// test screenA
}
And then from within the app
// AppDelegate.swift
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = createRootViewController()
window.makeKeyAndVisible()
self.window = window
return true
}
...
// Can be extracted to a helper class if it gets more complex (e.g. if dependencies are needed etc...)
extension AppDelegate {
func createRootViewController() -> UIViewController? {
// remember to update the project settings so it no longer automatically loads the storyboard
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var rootViewController = storyboard.instantiateInitialViewController()
#if DEBUG
// This is the basic idea, you can ofcourse clean this up by having some helper classes / enums etc...
let environment = ProcessInfo.processInfo.environment
if let screenToLaunch = environment["screenToLaunch"] {
rootViewController = storyboard.instantiateViewController(withIdentifier: screenToLaunch)
}
#endif
return rootViewController
}
}
2) You can also use XCUIApplication.launchArguments which is very similar to the approach above, launch arguments however is a [String]
One cool thing you can do with LaunchArguments is, if you store values in the follow format
let app = XCUIApplication()
app.launchArguments = ["-someKey","someValue"] // note the '-' before the <key>
This would add to / override NSUserDefaults in the main app while its running!
// somwhere in the app
UserDefaults.standard.value(forKey: "someKey") // returns "someValue"
Using a combination of both these techniques you can start creating Mocks in the main app which your UI test can configure!
Hope this helps