How To Automate iOS App Using Appium
Tags: showdev, webdev, javascript, beginners
Published: 2023-01-02 14:02:49



Mobile apps have been an inseparable part of daily lives. Every business wants to be part of the ever-growing digital world and stay ahead of the competition by developing unique and stable applications.

Among all the mobile operating systems available in the market, current research states that iOS is the second most popular mobile operating system. There are some strong reasons behind it. Firstly, iOS is not restricted by any zonal or language barrier. Secondly, it supports 40 different languages, giving users a broader option globally.

![](https://cdn-images-1.medium.com/max/2432/0*XWF2Ds07qr-zMa9U.png)

According to the report, Apple sells nearly 200 Million iPhones annually, and Apple users download an average of 51 apps per minute. [Developing an intuitive app](https://www.lambdatest.com/blog/key-to-intuitive-mobile-ux/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) is just half the battle won, as the second half can only be won if the app is fully functional and creates a lasting impression on the users. This is why rigorous [iOS automation testing](https://www.lambdatest.com/ios-automation-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage) of apps becomes an absolute necessity!

To ensure that the iOS app runs flawlessly, you must ensure that [mobile app testing](https://www.lambdatest.com/mobile-app-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage) is planned and executed perfectly. To achieve it, you need to use a framework like [Appium](https://www.lambdatest.com/appium?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage) to run iOS app testing on real iOS devices at scale. The result is wider coverage and faster execution with utmost quality.

This [mobile app testing tutorial](https://www.lambdatest.com/learning-hub/mobile-app-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=learning_hub) on performing [Appium testing](https://www.lambdatest.com/appium-mobile-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage) of iOS devices will help you answer all questions pertaining to how to automate iOS app using Appium.

***Check this out: [Black Box Testing](https://www.lambdatest.com/learning-hub/black-box-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=learning_hub) Tutorial: A Comprehensive Guide With Examples and Best Practices***

## Types of iOS application testing

There are specifically two types of iOS application testing, either you can test it using the **simulator** or by using the **real device**. In most real-time projects, the team prefers to perform [regression testing](https://www.lambdatest.com/blog/regression-testing-what-is-and-how-to-do-it/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) in the [iOS simulator](https://www.lambdatest.com/ios-simulator-online?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage), but [simulator testing](https://www.lambdatest.com/blog/setting-up-an-ios-simulator-for-testing/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) alone is insufficient for QA sign-off. This is why test (or QA) teams prefer to execute one round of Smoke or Sanity on the real devices.

When teams perform iOS testing, they like to run [Functional Testing](https://www.lambdatest.com/blog/automated-functional-testing-what-it-is-how-it-helps/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog), [Performance Testing](https://www.lambdatest.com/infographics/performance-testing-basics?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage), Security Testing, and Hardware Testing. It is important to note that Performance, Security, and Hardware Testing are non-functional testing types.

In this [Appium testing tutorial](https://www.lambdatest.com/blog/appium-tutorial/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog), we will perform functional testing on iOS using a [real device cloud](https://www.lambdatest.com/real-device-cloud?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage).

Many [mobile app testing frameworks](https://www.lambdatest.com/blog/best-mobile-app-testing-framework/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) facilitate [automated device testing](https://www.lambdatest.com/automated-device-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage) on iOS. However, my personal choice has always been “Appium.” You will know about the USPs of Appium once you read through this blog on how to automate iOS app using Appium.

![](https://cdn-images-1.medium.com/max/2000/0*UqpsUl7B64Ww6bBK.png)

***Check this out: [System Testing](https://www.lambdatest.com/learning-hub/system-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=learning_hub) Tutorial: A Comprehensive Guide With Examples and Best Practices***

## What is Appium?

Appium is an open source [test automation framework](https://www.lambdatest.com/blog/best-test-automation-frameworks-2021/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) for automating native, mobile web, and hybrid applications on iOS devices, Android devices, and Windows desktop platforms. Importantly, Appium is “cross-platform”: it allows you to write tests against multiple platforms (iOS, Android, Windows) using the same API.

In simple words, it processes the request from the client and forwards it to the [simulator and emulator](https://www.lambdatest.com/blog/difference-between-emulator-vs-simulator-for-mobile-testing/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) or real devices. The test scripts are automated, and the result is communicated to the client via the server. This [emulator vs simulator vs real device testing](https://www.lambdatest.com/blog/emulator-vs-simulator-vs-real-device/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) blog will help you learn more about it.

This enables code reuse between iOS, Android, and Windows test suites. The best part is using programming languages such as JavaScript, Java, Ruby, Python, PHP, and C# for Appium test script design.

As per the official website of Appium, per month, around 416k downloads are done by the users. It has a massive number of users along with community support.

![](https://cdn-images-1.medium.com/max/3998/0*OgUsfANAb5Zcorux.png)

Watch this video to learn about Appium, one of the most popular open-source test automation frameworks for mobile app testing.

{% youtube Z_J8RmQf7Nw %}

***Check this out: [Exploratory Testing](https://www.lambdatest.com/learning-hub/exploratory-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=learning_hub) Tutorial: A Comprehensive Guide With Examples and Best Practices***

## Benefits of automating iOS app testing using Appium

As discussed earlier in this blog on how to automate iOS app using Appium, you must have had a little idea about iOS and Appium by now, but the million-dollar question is **why Appium?**

Appium has shown significant progress and is quickly becoming a preferred [automation testing tool](https://www.lambdatest.com/blog/automation-testing-tools/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) for mobile applications, with 35% of the organizations choosing it over other free/open source functional testing tools.

![](https://cdn-images-1.medium.com/max/2000/0*uet4YnXW0XoB4Xrj.png)

So, let’s point out some of the significant benefits of Appium for iOS app testing. We have alternatives for iOS automation, but Appium is easy to use and has extensive community support.

* **Cross platform**

Appium is “cross-platform”. This means you can use the same tests across multiple platforms (iOS, Android, Windows). Not a single line of code change is required when using the APIs. This helps in making the test scripts more modular.

* **Avoid installing extra dependencies**

From Appium 1.15.0, Appium communicates with a real device via **appium-ios-device**. You no longer have to install extra dependencies. The official documentation on **appium-xcuitest-driver** is also helpful in resolving dependencies

* **Support for major iOS versions**

Appium supports major versions of iOS. iOS version 9.3 and above is supported by Apple [XCUITest](https://www.lambdatest.com/xcuitest?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage), and the lower to 9.3 version is supported by Apple’s UI Automator. Learn more about XCUITest through this [XCUITest testing](https://www.lambdatest.com/xcuitest-app-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage) tutorial.

* **Avoid recompilation of app**

Appium does not require recompilation of App. It means we don’t need to implement a thing in the application code. While other frameworks need you to implement some change inside your code. It simply means there is no need to open the project in XCode. Just use the .app file to automate the application

* **Hassle-free execution**

Appium supports [real devices cloud testing](https://www.lambdatest.com/blog/real-device-cloud/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) and testing on simulators and emulators. It gives the flexibility to execute the automation suite across the platforms.

In case you are a beginner to Appium you can learn to perform mobile app testing easily through this tutorial.

{% youtube pI5zrUhydyo %}

As stated on the official website of Appium, the Appium team does not test the XCUITest driver against jailbroken devices, so it cannot be guaranteed that it will work as seen on non-jailbroken devices.

Automate your iOS apps on the Appium cloud of 3000+ real devices. [Try LambdaTest Now!](https://accounts.lambdatest.com/register?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=register)

## Prerequisites for how to automate iOS app using Appium

Before starting the pre-setup, as per my past experiences, I must tell you that it is quite tedious to do the entire setup, so please stay with us and follow all the steps carefully. Remember that all the steps mentioned below are mainly specific to OS, so follow steps respective to your operating system (i.e., macOS, Windows).

 1. First, you must have the Java setup done along with an IDE. We can use any IDE, but I recommend using Eclipse or IntelliJ IDE. I would recommend using Eclipse for the first try or practice.

 2. To set up JDK in the machine, please refer to the official Oracle website. If you already have JDK in your machine, skip this step. Never forget to check your java version in your machine post installation. You can also check the Java version as below once the installation is completed:

![](https://cdn-images-1.medium.com/max/2400/0*kCV6R7yhzjLQX3S1.png)

3- Once your JDK installation along with environment setup is done, the next step is supposed to install Eclipse. For your help, please refer to these blogs on [how to install Eclipse](https://www.lambdatest.com/blog/setup-junit-environment/#eclispeides?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) and [how to install IntelliJ](https://www.lambdatest.com/blog/setup-junit-environment/#intellij?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog).

{% youtube QFHMzWqDPiA %}

You can also subscribe to the [LambdaTest YouTube Channel](https://www.youtube.com/channel/UCCymWVaTozpEng_ep0mdUyw?sub_confirmation=1) and stay updated with the latest tutorials around [Selenium testing](https://www.lambdatest.com/selenium-automation?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage), [Cypress E2E testing](https://www.lambdatest.com/cypress-e2e-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage), CI/CD, and more.

**Step 1: Install Homebrew**

It is a package management software, and to install, follow the instructions on this page: https://brew.sh/.

To check the installed details along with the version, we can type “brew -v” as shown below:

![](https://cdn-images-1.medium.com/max/2344/0*eXHMZ6R6GM21TkT5.png)

**Step 2: Install Carthage**

The WebDriverAgent requires it. To install it, just type below command:

   

```
 brew install carthage
```

If it is already installed in your machine, then you will get a message as below:

*“carthage 0.38.0 is already installed and up-to-date.”*

**Step 3: Install Node & Npm**

This step is required because Appium is a node application. To install it, run the below command on the terminal.

```
    brew install node
```

To verify the installed versions of npm and node, we can use npm -v & node -v as shown below:

![](https://cdn-images-1.medium.com/max/2000/0*QkCKLIgqSuVAjmX2.png)

**Step 4: Install authorize-ios**

authorize-ios is a little utility that pre-authorizes Instruments to run UIAutomation scripts against iOS devices. It is required to run tests on real devices.

In the terminal, enter the below command to install authorize-ios:

    

```
npm install -g authorize-ios
```

**Step 5: Install ios-deploy**

Install ios-deploy via Homebrew by running the below command on the terminal:

 

```
   brew install ios-deploy
```

To verify the installation, we can use ios-deploy –version command in the terminal as below:

![](https://cdn-images-1.medium.com/max/2000/0*ESATIUAyY5KNWzvY.png)

**Step 6: Install ideviceinstaller**

This is the tool for managing apps on iOS device

```
    brew install ideviceinstaller
```

To check the installation is completed or not, ideviceinstaller –version command can be used as shown below:

![](https://cdn-images-1.medium.com/max/2080/0*kkqsKXMN9yRXoW30.png)

**Step-7: Install Xcode**

Xcode is a complete developer toolset for creating apps for Mac, iPhone, iPad, Apple Watch, and Apple TV. Xcode brings user interface design, coding, testing, debugging, and submitting to the App Store into a unified workflow.

For step-by-step guidance on using Xcode to build, test, and submit apps to the App Store, look at XCode documentation. To verify the Xcode installation, we can use the **/usr/bin/xcodebuild** -version command as shown below:

![](https://cdn-images-1.medium.com/max/2016/0*cb06QhxVXGpCxDn3.png)

**Step 8: Install XCUITest driver**

Appium XCUITest driver is a combined solution, which allows automated black-box testing of iOS and tvOS native applications and WebKit web views. The native testing is based on Apple’s XCTest framework and the fork of Facebook’s WebDriverAgent server.
Web views communication is done via Webkit remote debugger protocol.

The appium-ios-device library ensures real device communication. To install the XCUITest driver, please use the official website. It has the help doc, which can be referred to for common errors or issues faced during the installation.

**Step 9: Install Appium and Appium Doctor**

To install Appium, please type the below command and use the version of Appium after @ in the below command:

  

```
  npm install -g appium@version
```

You can check the version of Appium installed by using the command **appium –version** on the terminal, refer the below screenshot for reference:

![](https://cdn-images-1.medium.com/max/2000/0*XE1rgG2-0J6Zf_Db.png)

Appium doctor is a mini software that checks all (well, almost all) of the preconditions for appium to run successfully. In the terminal, enter the following:

 

```
   npm install -g appium-doctor
```

We can use the command **appium-doctor –version** to check the installed version:

![](https://cdn-images-1.medium.com/max/2000/0*0Zz5y6H4AtszhBKE.png)

**Step 10: Install Maven**

As we all know, Maven is the dependency management tool, type below command in your terminal:

  

```
  brew install maven
```

Don’t forget the setup maven path before checking the version, you can do that by using below command:

 

```
   ​​export PATH=/opt/apache-maven-3.8.6/bin:$PATH
```

Once installation complete do cross-check by typing below command:

  

```
  mvn — version
```

Output will look as below:

![](https://cdn-images-1.medium.com/max/3998/0*Hz7MxwDafQ6pgAaQ.png)

**Step 11: Install TestNG**

TestNG is a testing framework that we’ll be using to manage our automated test suite. Launch Eclipse, select “Help” > “Eclipse Marketplace”–>search for TestNG. Learn more about TestNG through this [Selenium TestNG tutorial](https://www.lambdatest.com/learning-hub/testng?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=learning_hub).

We should be able to see the TestNG for Eclipse option with a button as “Install.” Click on the button and complete the installation. For more help, please go through this [Appium with TestNG](https://www.lambdatest.com/blog/appium-with-testng-tutorial/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) tutorial.

**Step 12: Install Appium Desktop**

We need to install Appium Desktop so we can use the [Appium Inspector](https://www.lambdatest.com/blog/appium-inspector-for-apps/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog) to identify the elements on the iOS app for designing test scripts. You can install the Appium Desktop from the official website.

## Capabilities setup for real iOS device

This is the most vital step to perform. Below are the mentioned capabilities we require to run our tests.

```
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("platformName", "iOS");
        capabilities.setCapability(MobileCapabilityType.NO_RESET, true);
        capabilities.setCapability("useNewWDA", false);
        capabilities.setCapability("platformVersion", "12.0.1");
        capabilities.setCapability("deviceName", "iPhone 8");
        capabilities.setCapability("udid", "auto");
        capabilities.setCapability("bundleId", "<your bundle id>");
        capabilities.setCapability("xcodeOrgId", "<your org id>");
        capabilities.setCapability("xcodeSigningId", "iPhone Developer");
        capabilities.setCapability("updatedWDABundleId", "<bundle id in scope of provisioning profile>");
        capabilities.setCapability(MobileCapabilityType.APP, "[PATH_TO_YOUR_IPA_FILE]");
```

Now the question is how to get the details that have been mentioned in the above code. Let’s go through them one by one:

* **platformVersion**: is the version of iOS our app is running, 12.0.1 in my case.

* **deviceName**: is not required, as we have plugged in a real device and will select that device using the udid desired capability. Appium still requires us to supply a value for deviceName, so we use iPhone 8. To know the device name, in the iPhone, we can navigate to“Settings> General > About > Name.”

* **udid**: is the unique ID of the device we want to run our test on. Now connect your iPhone to your computer by USB and load up iTunes. We could find our device udid by running the command instruments -s devices in the terminal. Still, since we only have a single device plugged in, we can put in auto, and Appium will automatically find the udid of the device for us and use it. If ”auto” doesn’t work, then do provide your udid.

* **xcodeOrgId & xcodeSigningId**: join the Apple Developer Program and locate your apple developer team id; xcodeorgid is the ID of the developer team that signed the certificate used to create the app. xcodeSigningId is the first part of the “Common Name” associated with the developer certificate.

* Since XCode set this up for us, it is almost always iPhone Developer, but it could be something different for you if you are automating a different iOS device.

* **bundleID**: it is the special iOS-internal name of our app. The easiest way to get the bundleID is by using iTunesConnect. The steps are as below:

 1. Log into iTunes Connect.

 2. Click My Apps.

 3. Click on an app to find the bundle ID.

 4. The default app page will open, displaying the App ID and bundle ID.

* **App**: many websites provide the sample apk, which can be used for testing. If you do not have any .apk or .ipa files, you can run your sample tests on LambdaTest using our sample 🔗 iOS app.

* **noReset**: do not forget to use this capability. This approximately saves 2.9 seconds per test by avoiding app installation before every test run.

* **updatedWDABundleId**: we need to create a provisioning profile for signing the WebDriverAgentRunner. Launch the Xcode and create a new project, select the team and enter the project name as follows:

![](https://cdn-images-1.medium.com/max/2764/0*k47zYd-PvpZGrX_l.png)

Take a look at the “Project” tab of your project settings to confirm that “Automatically manage signing” is selected, and an Xcode Managed Profile is created.

![](https://cdn-images-1.medium.com/max/2000/0*a33zKJ4IO-oDHyQV.png)

Suppose you manually try to run the WebDriverAgentRunner app on the device. In that case, you will see a popup message:

![](https://cdn-images-1.medium.com/max/2000/0*vrv3i93uOZV_tbZr.png)

You can go to Settings => General => Device Management on the device to trust the developer and allow the WebDriverAgentRunner app to be run.

Copy your bundleId and add the following capability to your Appium Capabilities setup:

 

```
   capabilities.setCapability(“updatedWDABundleId”, “<bundle id in scope of provisioning profile>”);
```

If you are unable to do the above steps, then the manual configuration can also be done. To go through the steps, please refer to this document. It has all the steps along with the screenshots.

***Check this out: [UI Testing](https://www.lambdatest.com/learning-hub/ui-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=learning_hub) Tutorial: A Comprehensive Guide With Examples and Best Practices***

## Identifying the iOS elements

In this section of this blog on how to automate iOS app using Appium, we will learn how to identify the iOS elements. To identify elements in iOS devices, we need to download and install the Appium Desktop application and use the Appium Desktop Inspector functionality.

 1. If you have installed Appium Desktop, then we can start by clicking on the **Start Server** button inside of Appium Desktop as shown below.

![](https://cdn-images-1.medium.com/max/2000/0*H12H9J52ychUl7iS.png)

2- Click the search icon from the right-up corner.

![](https://cdn-images-1.medium.com/max/2000/0*lj_gmCCbxIcMhFPZ.png)

 1. Add correct desired capabilities per your device/emulator and application. Then click on the **Start Session** button.

![](https://cdn-images-1.medium.com/max/2400/0*pYoWEfjv2hdM3lBY.png)

4- It will open the App screen, App Source (the hierarchy of elements), and Selected Element Pane (The attributes and associated values of the element). You can use this to create locators which will uniquely identify the element.

5- You can provide a .ipa file in desired capabilities inside Appium Inspector, which will install and launch the app. Refer to the screenshots below, which we have used to test .ipa and passed in the value against “app.” Use all the fields of desired capabilities discussed in this blog on how to automate iOS app using Appium. The best thing about the Appium Inspector is that you can verify your written locator on screen. Check the below screenshots.

![](https://cdn-images-1.medium.com/max/2000/0*Yy5EkOUmHOfkny58.png)

6- If your locator is correct, it will highlight the associated element, which is the same for Android and iOS.

![](https://cdn-images-1.medium.com/max/2000/0*xIvCq6S4lry7erUr.png)

Some of the most used [locator strategies](https://www.lambdatest.com/learning-hub/selenium-locators?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=learning_hub) are mentioned below.

<table>
    <tr>
        <td>STRATEGY</td>
        <td>DESCRIPTION</td>
    </tr>
    <tr>
        <td>Accessibility ID</td>
        <td>Reads a unique identifier for a UI element. For XCUITest, it is the element’s accessibility-id attribute. For Android, it is the element’s content-desc attribute. </td>
    </tr>
    <tr>
        <td>Test that you can filter for an item on the filter box.</td>
        <td>For iOS, it is the full name of the XCUI element and begins with XCUIElementType. For Android, it is the full name of the UIAutomator2 class (e.g., android.widget.TextView) </td>
    </tr>
    <tr>
        <td>ID</td>
        <td>Native element identifier. resource-id for Android; name for iOS.</td>
    </tr>
    <tr>
        <td>Name</td>
        <td>	Name of element.</td>
    </tr>
    <tr>
        <td>XPath</td>
        <td>	Searches the app XML source using xpath (not recommended, has performance issues).</td>
    </tr>
    <tr>
        <td>Image</td>
        <td>	Locates an element by matching it with a base 64 encoded image file.</td>
    </tr>
    <tr>
        <td>iOS UIAutomation</td>
        <td>When automating an iOS application, Apple’s Instruments framework can be used to find elements.</td>
    </tr>
</table>


In most real time projects, one public webelement is created, and element identification for Android and iOS is mentioned, as shown below. The nameOfMobileElement mentioned below is just an example. You can replace the same with the name of the locator used to identify the webelement of the targeted mobile app. We have identified the iOS element using iOSNsPredicate.

```
        @iOSXCUITFindBy(iOSNsPredicate = "name=='<nameOfMobileElement>'")
        @AndroidFindBy(uiAutomator = "text(\"<textOf TheMobileElement>\")")
        public MobileElement elementName;
```

We can also use XPath as mentioned below for identification in iOS, in-fact all type of axes methods in XPath can be used to identify the element uniquely:

```
            @iOSXCUITFindBy(xpath = "//*[@name='<nameOfMobileElement>']/following-sibling::XCUIElementTypeStaticText")
```

Though in my past experiences the most used identification I have used is accessibility as below, “GO TO APP” is just an example, it should be replaced with the accessibility for the app used for testing:

 

```
   @iOSXCUITFindBy(accessibility = “GO TO APP”)
```

While identifying iOS elements, we need to remember that the element should always be unique and try the locators first and give XPath identification the least priority. I would suggest not using XPath locators unless there is no other alternative.

In general, XPath locators might be much slower than other locators like accessibility id, class name, and predicate (up to 100 times slower in some special cases). They are so slow because Apple’s XCTest framework does not natively support the XPath location.

***Check this out: [Agile Testing](https://www.lambdatest.com/learning-hub/agile-testing?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=learning_hub) Tutorial: A Comprehensive Guide With Examples and Best Practices***

## Demo Code for automating iOS app using Appium

Before running the tests, we need to perform below two steps:

**Step 1**: Make sure the device which will be used for testing is unlocked, and if it asks you to “Trust the Computer”, tap the button to trust our Mac. You’ll need to do this the first time, and it won’t ask for it.

**Step 2**: Start the Appium server.

  

```
  import io.appium.java_client.MobileBy;
    import io.appium.java_client.MobileElement;
    import io.appium.java_client.ios.IOSDriver;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import io.appium.java_client.remote.MobileCapabilityType;
    import org.junit.Before;
    import org.junit.Test;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    public class iOS_Test {
        private IOSDriver driver;
    
        @Before
        public void setUp() throws MalformedURLException {
            DesiredCapabilities capabilities = new DesiredCapabilities();
            capabilities.setCapability("platformName", "iOS");
            capabilities.setCapability("platformVersion", "15.5");
            capabilities.setCapability("deviceName", "Sidiphone");
            capabilities.setCapability("udid", "auto");
            capabilities.setCapability("bundleId", "<your bundle id>");
            capabilities.setCapability("xcodeOrgId", "<your org id>");
            capabilities.setCapability("xcodeSigningId", "iPhone Developer");
            capabilities.setCapability("updatedWDABundleId", "<bundle id in scope of provisioning profile>");
            capabilities.setCapability(MobileCapabilityType.APP, "[PATH_TO_YOUR_.IPA_FILE_COMPILED]");
            driver = new IOSDriver<>(new URL("http://localhost:4723/wd/hub"), capabilities);
        }
    
        @Test
        public void testClickAnElement() throws InterruptedException {
            //Opens the browser
            MobileElement browser = (MobileElement) driver.findElementByAccessibilityId("Browser");
            browser.click();
            Thread.sleep(3000);
    
            WebDriverWait el7 =  new WebDriverWait(driver, 30);
            el7.until(ExpectedConditions.elementToBeClickable(MobileBy.id("url")));
            driver.findElementById("url").sendKeys("https://www.lambdatest.com/");
    
            //Clicks on the text box
            WebDriverWait el = new WebDriverWait(driver,90);
            MobileElement el4 = (MobileElement) driver.findElementByAccessibilityId("find");
            el.until(ExpectedConditions.elementToBeClickable(el4));
            el4.click();
            el4.sendKeys("LambdaTest");
    
            //((JavascriptExecutor) driver).executeScript("lambda-status=passed");
            driver.quit();
    
        }
    }

```
In the above code, the Test method we have used is testClickAnElement(), and the element we are trying to click is from the iOS app shared in this post on how to automate iOS app using Appium.

![](https://cdn-images-1.medium.com/max/2000/0*IiGM4EA35kHbZqA8.png)

## Troubleshooting Tips

 1. Make sure UDID is correct by checking it in XCode Organizer or iTunes. It is a long string (approx 20+ chars).

 2. Make sure the following settings are **enabled** on your device:

**A.** Settings -> Developer -> **Enable UI Automation**
**B.** Settings -> Safari -> Advanced -> **Web Inspector** and **Remote**

3- Consider generating a provisioning profile with a .xctrunner identifier if you do not want to generate a wildcard one for manual configuration. The .xctrunner config support has been added since XCode 11.

4- Make sure the provisioning profile has an iOS Distribution certificate. An active XCode/xcodebuild connection/session is necessary to interact with WebDriverAgentRunner because of Apple’s security design. The certificate affects the limitation.

5- The keyboard preference in the device under test is Apple’s official one, and the input language is set to English to send texts to XCUIElementTypeSecureTextField, as Non-official or non-English keyboards may not be able to send keys to XCUIElementTypeSecureTextField.

## Limitations

Given that Appium uses instruments underneath, we have all of the limitations of using Apple’s automation framework. This includes:

* A slower response time between actions, automation that can only run over a USB tether, and only one device can execute automation simultaneously per host.

* Each physical device or simulator requires a separate host running on a Mac to communicate with each device. This is due to the hosts being the one who determines where the commands are communicated, regardless of what parameters are passed into the automation. This may be a bug in the Appium infrastructure or requires a special command to determine the device to execute from the automation code.

* The Instruments log files are not returned as part of the test, and the data given back to the running test is much less than what is seen in a typical Instruments test case.

## How to automate iOS app using Appium on a real device cloud?

In this blog on how to automate iOS app using Appium, you must have realized that testing on real devices is not a cakewalk, especially iOS real device testing is tedious. The important thing is that real iOS device testing can only take place on a Mac, so we can’t even perform real iOS device testing without a Mac.

As a result, most organizations prefer to use [real cloud devices for testing](https://www.lambdatest.com/blog/real-device-cloud-testing/?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=blog). You can try LambdaTest cloud devices, which are quite easy to use, and we can avoid setting up all the prerequisites on local machines.

LambdaTest provides a cloud-based solution for [mobile automation testing](https://www.lambdatest.com/mobile-automation-test?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage). It lets you automate native and hybrid mobile apps on an [online device farm](https://www.lambdatest.com/online-device-farm?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage) of 3000+ real iOS. It is a scalable, secure, and high-performing Appium testing platform that empowers development and testing teams to accelerate their release cycles.

{% youtube vDHFbEjXxdc %}

Below we have executed the test suite using LambdaTest real cloud devices. Just use the below code along with your username and password. We used the iPhone 12 for our test run. You can use the model as per the requirement.

```
    import io.appium.java_client.AppiumDriver;
    import io.appium.java_client.MobileBy;
    import io.appium.java_client.MobileElement;
    import io.appium.java_client.ios.IOSDriver;
    
    import org.openqa.selenium.remote.DesiredCapabilities;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    import java.net.URL;
    
    public class vanilla_ios {
    
        public static String userName = System.getenv("LT_USERNAME") == null ? "sidharth****"  //Add username here
                : System.getenv("LT_USERNAME");
        public static String accessKey = System.getenv("LT_ACCESS_KEY") == null ? "********" //Add accessKey here
                : System.getenv("LT_ACCESS_KEY");
    
        public static final String URL = "https://" + userName + ":" + accessKey + "@beta-hub.lambdatest.com/wd/hub";
        public static IOSDriver driver = null;
    
        public static void main(String[] args) throws Exception {
    
           try {
                DesiredCapabilities caps = new DesiredCapabilities();
                caps.setCapability("platformVersion", "15");
                caps.setCapability("deviceName", "iPhone 12");
                caps.setCapability("isRealMobile", true);
                caps.setCapability("app", "******"); //Enter your app url
                caps.setCapability("platformName", "iOS");
                caps.setCapability("build", "Java Vanilla - iOS");
                caps.setCapability("name", "Sample Test Java");
                caps.setCapability("devicelog", true);
                caps.setCapability("network", true);
    
    
            driver = new IOSDriver(new URL("https://" + userName + ":" + accessKey + "@beta-hub.lambdatest.com/wd/hub"), caps);
    
    
                Thread.sleep(2000);
    
                //Opens the browser
                MobileElement browser = (MobileElement) driver.findElementByAccessibilityId("Browser");
                browser.click();
                Thread.sleep(3000);
    
               WebDriverWait el7 =  new WebDriverWait(driver, 30);
               el7.until(ExpectedConditions.elementToBeClickable(MobileBy.id("url")));
               driver.findElementById("url").sendKeys("https://www.lambdatest.com/");
    
                //Clicks on the text box
                WebDriverWait el = new WebDriverWait(driver,90);
                MobileElement el4 = (MobileElement) driver.findElementByAccessibilityId("find");
                el.until(ExpectedConditions.elementToBeClickable(el4));
                el4.click();
                el4.sendKeys("Lambdatest");
    
                //((JavascriptExecutor) driver).executeScript("lambda-status=passed");
                driver.quit();
    
            } catch (Exception t) {
               System.out.println(t);
               driver.quit();
    
           }
        }
    }
```

In the above script, we have first done the capabilities setup and then automated the iOS app with two steps:

The first one is to open the browser and the second one is to click on the text box and then enter text “LambdaTest” on the text box. For ease of execution, we have used thread.sleep in this blog on how to automate iOS app using Appium. You can ignore the same while executing in your setup.

 1. To execute the same, you need to use the below two commands on your terminal:

       

```
 mvn clean install
```

2- Once you execute the command, you should get the Build Success message as below:

![](https://cdn-images-1.medium.com/max/2400/0*90DEd3wffGxRQgpn.png)

After that, we need to execute the test cases using the below command on the terminal:

    

```
    mvn test -P ios
```

3- Once the above command executes successfully, we must go to the LambdaTest website and validate the runs. Navigate to the Real Device ⇒ App Automation Section. You should be able to see “Java Vanilla — iOS” as shown below:

![](https://cdn-images-1.medium.com/max/2400/0*EF_FzIzvgMhs9CYq.png)

4- Now click on the recent execution. You will be redirected to the build view page, where all the details about the execution will be displayed along with the video:

![](https://cdn-images-1.medium.com/max/2400/0*2GDFp5Xx_ujRPKSY.png)

5- In the above, we can check the Test Logs and Network details. Isn’t it relatively easy to run the automation suite on real cloud devices compared to doing the entire setup on a local machine? The best part is selecting any iPhone model required for your testing.

![](https://cdn-images-1.medium.com/max/2000/0*i2crA0XWHEtIQodC.jpg)

***Check this out: Jest Tutorial: Complete Guide to [Jest Testing](https://www.lambdatest.com/jest?utm_source=devto&utm_medium=organic&utm_campaign=jan02_sd&utm_term=sd&utm_content=webpage)***

## Conclusion

With this, we have concluded this tutorial on how to automate iOS app using Appium. As per my suggestion, we should only consider real iOS devices for Sanity or Smoke suite execution. For regression, it is always advised to use either simulators or cloud devices.

Though we have simulators, we should never release a product without being tested on real devices, so better to prepare an automation suite and run the real devices on the cloud, saving time and ensuring quality.

We can address most app-related issues by ensuring that the app works on a real device. iOS testing with Appium will help provide that confidence in the product and confirm the app’s success when it is released to users.

Happy testing, and do share what should be the next topic you want to learn.

![](https://cdn-images-1.medium.com/max/2000/0*2hlPT9bZq10pcSBg.png)