Setting Up XCUITest Framework for iOS App Testing in Xcode 10

Apple announced the Xcode UI Testing framework in WWDC 2015 that allows us to write user interface tests for iOS apps using Swift or Objective-C. The only option remained to automate iOS apps is the XCUITest framework. Since iOS 10, there is a growing trend of iOS teams adopting XCUITest and deprecating old toolbox. In this short post, we will explore 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 that is 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 the UI element and validate its position or state in our apps.

XCUITest framework allows us to write UI tests straight inside the Xcode with the separate UI testing target in the app. We can use Apple’s own programming languages e.g. Swift or Objective-C for writing UI Tests in the Xcode. XCUITest runs in the separate process from our main iOS app and it doesn’t have to access application’s internal methods, API or data. XCUITest uses Accessibility technology to interact with the main iOS app, which means application developers need to provide accessibility information for UI elements to make apps accessible as well as testable.

Setting Up UI Testing in iOS App

The process of setting up Xcode UI testing in the existing iOS app is very straightforward. It involves a few tasks as mentioned below. And if you want to take your XCUITest tests to a mobile device testing cloud service and run 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 the Github which has the enter button on the home screen and when a user taps on the button it shows “Welcome to XCUITest” message.

Want to run your XCUITest tests against real iOS devices?

We offer a mobile device cloud with real iOS devices for automated and manual testing. Sign up for a 30-day trial.

Creating UI Test Target and Scheme

Now that we have our app ready to be tested, we will setup UI testing target for our app, assuming your app doesn’t have any target dedicated for the UI testing. We can easily add new target using Xcode by following below steps.

  • Open Xcode Project/workspace of iOS app in Xcode and add new target by selecting File –> New –> Target
  • Choose a template for your new target by selecting iOS tab and UI Testing Bundle 

  • Click Next. The next screen we need to fill the Target name, team, bundle identifier details. If you are working on an iOS app that has the team setup then you can use that team. Xcode will generate some fields by default. Select the language of writing tests e.g Swift. Click Finish

  • Once finished above step, we will have brand new UITest target XCUITest101UITest set for XCUITest and Apple has provided the template code with sample test.

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 XCUITest target. We can create the 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.

  • From Xcode Menu Select, Product —> Scheme —> New Scheme.

Select the UI Test target, XCUITest101UITest and name your new scheme. Click OK and you will have a new scheme in Xcode for UI Test. 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 customise the build, test and archive options. In our UI Test target, we can customise the Test option. Don’t forget to share your scheme from the checkbox otherwise, it won’t be seen by CI Server or Source Control. The sample UITest scheme in Xcode 10 looks like this 

Recording/Writing XCUITests

XCUITest framework comes up with the 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 the tool, it’s good to know some basics of how to use it.

Download this essential guide to XCUITest/XCTest for successful iOS app testing

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 have to click inside the test method before recording otherwise we won’t see recorder enabled. We can rename the sample test with testRecorded() and click inside the test method. Once we click on the red dot then XCUITest will build an app with latest source code.

When the app is running in the simulator we can browse an app like a real user and XCUITest will record the test code in the Xcode. As our app is fairly simple as it has just “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 generated code works, it’s not reusable and scalable as we don’t have any assertions there and random taps are being recorded and it tricky to record inside the web views and sliders. It’s a good idea to use recorder as a reference but write tests yourself using XCUITest API. Now that we have recorded test and Xcode scheme configured for running tests. As we can see that the recorded test doesn’t have any assertion, we can write the same test by asserting that welcome message appears when the user taps on the enter button.

func testRefactored() {
        let app = XCUIApplication()
        app.buttons["enter"].tap()
        XCTAssert(app.staticTexts["Welcome to XCUITest"].exists)
    }

XCUITest has great API document in Apple developer site that can help us to write more tests. XCUITest has three main classes that support almost all user interactions that we can imagine. 

We can launch an app using XCUIApplication().launch()

  • XCUIElement: This class used to determine the UI element in the app and able to perform any action on it e.g tap, double tap, swipe etc 

We can tap on the button using this class. e.g. XCUIApplication().butons["enter"].tap()

  • XCUIElementQuery: This class can be used to uniquely identify the UI element on the screen. 

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 XCUIApplication().

buttons.element(boundBy: 0)

There are so many things, we can check using XCUITest API. 

Try It Yourself: Source Code 

The source code of this tutorial is available on the Github repo XCUITest101. Download the source code and open it in the Xcode 10. Select iPhone Simulator and Press CMD+U to see the tests running in the iPhone simulator. 

Conclusion

We have seen how to configure UI testing target and schemes to run XCUITests and wrote a simple test to check user gets the welcome message when entered in 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, pattern 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.


An Essential Guide to XCTest Framework for iOS App Testing

Get all essentials about XCTest framework and learn how to get started with it for cloud testing

Download