Setting Up XCUITest for iOS Testing in Xcode 10
Learn how to get started running unit tests for iOS with Xcode 10. In this post, we'll focus on two popular languages for iOS development: Swift and Objective-C.
Join the DZone community and get the full member experience.Join For Free
At WWDC 2015, Apple announced the Xcode UI Testing framework that allows us to write user interface tests for iOS apps using Swift or Objective-C. The only option remaining to automate iOS apps is the XCUITest framework. Since iOS 10, there has been a growing trend of iOS teams adopting XCUITest and deprecating their old toolbox. In this post, we will explore the steps to get started with XCUITest to automate iOS app testing with the latest Xcode 10.
Xcode UI Testing
Xcode UI testing is also known as XCUITest, a huge expansion of the testing technology in the Apple platform apps like iOS. With UI testing, we can simulate user actions in the simulators or devices to find out if our application is working with the latest changes in the code. With XCUITest, we can interact with UI elements and validate their position or state in our apps.
The XCUITest framework allows us to write UI tests right in Xcode with a separate UI testing target in the app. We can use Apple's own programming languages, like Swift or Objective-C, to write UI tests in Xcode. XCUITest runs in a separate process from our main iOS app and it doesn't have to access the application's internal methods, API, or data. XCUITest uses accessibility technology to interact with the main iOS app, which means that application developers need to provide accessibility information for UI elements to make apps accessible as well as testable.
Setting Up UI Testing in an iOS App
The process of setting up Xcode UI testing in an existing iOS app is very straightforward. If you want to take your XCUITest tests to a mobile device testing cloud service and run them against real iOS devices, it's suggested to configure it in a proper way.
- Creating UI test target and schemes
- Recording/writing XCUITests
- Running XCUITests
Let's briefly cover each of the steps with a sample app, XCUITest101, using Xcode 10. The sample app is available on GitHub. It has an
enter button on the home screen, and when a user taps on the button, it shows the message "Welcome to XCUITest."
Creating a UI Test Target and Scheme
Now that we have our app ready to be tested, we will set up a UI testing target for our app, assuming your app doesn't have a target dedicated for UI testing. We can easily add a new target using Xcode by following the below steps:
- Open the Xcode Project/workspace of the iOS app in Xcode and add a new target by selecting File -> New -> Target
- Choose a template for your new target by selecting the iOS tab and UI Testing Bundle.
Now that we have created the UI test target for our existing app, we need to configure a scheme to run our UI tests independently. We can use Xcode schemes to run our XCUITest without Xcode. In order to do that, we have to create a shared scheme for the XCUITest target. We can create a brand new scheme for XCUITest or attach our XCUITest target to an existing scheme. It's good practice to create a separate scheme so that we can run them independently.
Select the UI Test target,
XCUITest101UITest, and name your new scheme. Click OK and you will have a new scheme in Xcode for UI tests. We can always edit or check the content of the scheme from Xcode -> Product -> Scheme -> Edit Scheme. Now you can select the scheme we want to edit and customize the build, test, and archive options. In our UI Test target, we can customize the
Test option. Don't forget to share your scheme from the checkbox or it won't be seen by the CI server or source control. The sample UITest scheme in Xcode 10 looks like this:
XCUITest framework comes with a built-in recorder that helps us to record the user journey in the app that generates the sample code in the background. If you are not familiar with this tool, it's good to know some basics of how to use it.
You can find the recorder button at the bottom of the sample test as the red dot/circle. In order to start the recording of the test, we must click inside the test method before recording or we won't see recorder enabled. We can rename the sample test
testRecorded() and click inside the test method. Once we click on the red dot, XCUITest will build an app with the latest source code.
When the app is running in the simulator, we can browse the app like a real user and XCUITest will record the test code in Xcode. Our app is fairly simple, having just an "enter" button and static text. The recorded test will generate Swift code. We can play back this test by clicking the play button in Xcode in front of the test method. Although the generated code works, it's not reusable and scalable as we don't have any assertions, random taps are being recorded, and it's tricky to record inside the web views and sliders. It's a good idea to use the recorder as a reference, but write tests yourself using the XCUITest API. Now that we have recorded test and Xcode scheme configured for running tests. As we can see, the recorded test doesn't have any assertion; we can write the same test by asserting that a welcome message appears when the user taps on the enter button.
XCUITest has great API documentation on the Apple developer site that can help us write more tests. XCUITest has three main classes that support almost all user interactions that we can imagine.
We can launch an app using
We can tap on the button using this class, e.g.
We can form the query to uniquely identify the UI element on the screen. Imagine that you have to select the first button on the app. We can form the query like this
There are so many things we can check using the XCUITest API.
Try It Yourself: Source Code
The source code of this tutorial is available in the GitHub repo XCUITest101. Download the source code and open it in Xcode 10. Select iPhone Simulator and Press
CMD+U to see the tests running in the iPhone simulator.
We have seen how to configure a UI testing target and schemes to run XCUITests and wrote a simple test to check that the user gets the welcome message when they enter the app. As we go on writing more and more tests, we need to abstract common testing workflows to avoid code duplication. There are some good practices and patterns to structuring our code in a reusable and scalable format. We will be covering these topics in the next posts. If you have any questions, leave your comment below. Stay tuned.
Published at DZone with permission of Shashikant Jagtap, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
AWS Multi-Region Resiliency Aurora MySQL Global DB With Headless Clusters
The Native Way To Configure Path Aliases in Frontend Projects
Does the OCP Exam Still Make Sense?
Multi-Stream Joins With SQL