When UI testing a screen, it is sometimes helpful to test it in isolation. Rather than starting the app and going through a whole checkout process, you may want to just open the final screen directly and test it with different inputs. While this sounds straightforward, it’s not always obvious how to achieve it. In this post I’ll explain how we do it.
Setup the AppDelegate
As the entry point for your app, the AppDelegate is where we’ll do most of the work.
Breaking down the code above we can see a few components. The first if-statement checks if the app is running unit tests. While not directly relevant to this post, this ensures that when your app is launched for unit tests, none of your UI initialisation happens and hopefully increases startup times.
The second if-statement is what we’re most interested in. The way we’ll communicate between our test code and app code is through ProcessInfo. If the launch arguments contain UITestingEnabled, we know that the app is being launched from one of our UI tests and we can react accordingly. We can now check the launch environment to find out how to configure the app.
Define launch configurations
I’ve created an enum called LaunchScreen that defines the different screens that can be launched. This can contain any launch configurations you want, in the code below we’ll turn each configuration into a rootViewController to launch the app with.
Having turned the launch environment string into a LaunchScreen case, we call viewController(for: screen) which switches on the enum and calls another method to create a UIViewController. We can then use this UIViewController to initialise our UIWindow and set a rootViewController.
Setup the UI tests
With this in place we can create our UI test class. In the setUp() method, we just need to set the launch argument and environment that we mentioned earlier. This means that all tests in this class will be launched on the screen we want and in the state we want.
Adding new screens
To add a new launch screen, just:
- Add a case to the LaunchScreen enum
- Add it to the viewController(for screen:) switch
- Create a new viewControllerForXXX() method