Skip to content

I believe you’ve got a sense of XCUITest 101 series, in the first blog we will explore the process of setting up Xcode UI testing in the existing iOS app. 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

Setting Up UI Testing in iOS App

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.

Creating UI Test Target and Scheme

Now that we have our app ready to be tested, we will setup the UI testing target for our app, assuming your app doesn’t have any target dedicated for the UI testing. We can easily add a 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 the 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 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 otherwise, it won’t be seen by CI Server or Source Control. The sample UITest scheme in Xcode 10 looks like this

No time to read the blog? Take away this free XCUITest 101 ebook

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.

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 the 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 a 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. Read on and check out how to write DRY XCUITest tests with base classes.

Shashikant Jagtap

Mobile DevOps Engineer