
Introduction
The mobile development world is one of the most competitive landscapes out there, any good company such as zen8labs have to go to great lengths to ensure a good user experience across multiple iOS devices is crucial. Automation testing with Appium helps teams deliver high-quality apps by automating UI tests, reducing manual effort, and improving test reliability.
In this guide, I’m going to show you how I set up and run automation tests for iOS apps using Appium, WebdriverIO, and Bitrise CI/CD. I’ll share some real examples, handy tips, and the best practices that have worked well for me, plus a few debugging tricks.
Why choose Appium for iOS automation?
Appium is a powerful, open-source mobile automation framework that supports iOS and Android apps. It offers:
- Cross-platform support (Android & iOS)
- No need to modify the app (supports native, web, and hybrid apps)
- Integration with WebdriverIO for JavaScript-based tests
- Works with real devices & simulators
Use case: If you’re developing an iOS app with Flutter, Swift, or React Native, Appium allows you to test it on different iOS devices with a single test suite.
Comparing Appium with other mobile automation tools
When choosing an automation tool for mobile testing, it’s essential to compare Appium with other leading frameworks like XCUITest and Espresso.
Feature | Appium | XCUITest (ios only) | Espresso (android only) |
Cross-platform | Yes (iOS & Android) | No (iOS only) | No (Android only) |
Requires app modification | No | Yes (requires code instrumentation) | Yes (requires embedding into the app) |
Supports native & web apps | Yes | No (native only) | No (native only) |
Parallel execution | Yes | Yes | Yes |
CI/CD integration | Yes | Yes | Yes |
Performance | Slower compared to native tools | Fast | Fast |
Ease of setup | Requires Appium server & WebDriverAgent | Integrated in Xcode | Integrated in Android Studio |
The positives and negatives of the tools
Appium pros:
- Works for both iOS & Android, making it an excellent choice for cross-platform teams.
- No need to modify the app’s source code.
- Supports multiple programming languages (JavaScript, Java, Python, etc.).
- Open source with a large community.
Appium cons:
- Slower execution speed compared to XCUITest and Espresso due to its WebDriver-based architecture.
- Requires setting up Appium server and WebDriverAgent, which can be complex.
- Less stable on iOS, as updates in iOS can sometimes break compatibility.
XCUITest pros (for iOS):
- Faster execution since it’s natively integrated into Xcode.
- More stable for iOS apps as it’s maintained by Apple.
- No need for an external Appium server.
XCUITest cons:
- Only supports iOS (no Android support).
- Requires modifying the app by embedding test code.
Espresso pros (for Android):
- Fast execution as it runs directly within the app.
- Reliable and stable for Android UI testing.
- No need for an external server.
Espresso cons:
- Only supports Android (no iOS support).
- Requires embedding the Espresso testing framework into the app’s code.
Which one should you choose?
- If your team is building a cross-platform app (iOS & Android) → Appium is the best choice.
- If you are testing iOS-only apps → XCUITest is faster and more stable.
- If you are testing Android-only apps → Espresso is the best choice for speed and stability.
Pro tip: Many teams use Appium for cross-platform UI tests and combine it with XCUITest/Espresso for platform-specific optimizations.
Step 1: Setting up Appium for iOS
Before writing automation tests, you need to set up Appium and WebdriverIO on your local machine or CI/CD environment.
1.1 Install required dependencies
#Install Node.js & WebdriverIO
brew install node
npm install -g webdriverio appium
#Install Appium drivers for iOS
appium driver install xcuitest
#Ensure Xcode and WebDriverAgent are configured
xcode-select --install
Pro tip: If WebDriverAgent fails to launch, manually configure signing in Xcode for WebDriverAgentRunner.
Step 2: Writing your first Appium test
Now that our setup is ready, let’s write our first test using WebdriverIO.
2.1 Project structure
my-ios-tests/
├── tests/
│ ├── login-test.js # Example test file
├── wdio.conf.js # WebdriverIO configuration
├── package.json # Dependencies
2.2 WebdriverIO configuration (wdio.conf.js)
exports.config = {
runner: 'local',
specs: ['./tests/*.js'],
capabilities: [{
platformName: 'iOS',
'appium:deviceName': 'iPhone 14',
'appium:platformVersion': '17.7',
'appium:automationName': 'XCUITest',
'appium:app': '/path/to/your/app.app'
}],
framework: 'mocha',
reporters: ['spec'],
};
2.3 Writing a simple test (login-test.js)
describe('Login test', () => {
it('should log in with valid credentials', async () => {
const emailField = await $('~emailTextField');
await emailField.setValue('test@example.com');
const passwordField = await $('~passwordTextField');
await passwordField.setValue('SuperSecret123');
const loginButton = await $('~loginButton');
await loginButton.click();
});
});
Pro tip: Use ~ for accessibility IDs instead of XPath for better performance.
Step 3: Running tests on Bitrise CI/CD
3.1 Add WebdriverIO Tests to Bitrise Workflow
Modify bitrise.yml
to install dependencies, start Appium, and run tests:
workflows:
primary:
steps:
- script:
title: Install Appium & WebdriverIO
inputs:
content: |
npm install -g appium webdriverio
- script:
title: Run Appium Tests
inputs:
content: |
npx wdio run wdio.conf.js
Pro Tip: Use BITRISE_XCODE_TEST_DEVICE
to dynamically select the test device in CI/CD.
Step 4: Enhancing reports with Allure
To generate these detailed test reports, then you must integrate Allure:
4.1 Install Allure Reporter
npm install @wdio/allure-reporter --save-dev
4.2 Update wdio.conf.js to capture screenshots on failures
const allureReporter = require('@wdio/allure-reporter');
exports.config = {
reporters: [['allure', { outputDir: './allure-results' }]],
afterTest: async function (test, context, { error, passed }) {
if (!passed) {
const screenshot = await driver.takeScreenshot();
await allureReporter.addAttachment('Screenshot', Buffer.from(screenshot, 'base64'), 'image/png');
}
}
};
4.3 Generate Allure report
npx allure generate ./allure-results --clean
npx allure open
Pro Tip: Store the Allure reports in Bitrise Artifacts for easy access in CI/CD.
Final thoughts
Appium is a powerful automation tool for iOS apps, and when combined with WebdriverIO and Bitrise, it creates a robust mobile testing pipeline. By following this guide, you’ll:
– Set up Appium and WebdriverIO for iOS automation
– Run tests locally and on CI/CD
– Capture screenshots and generate reports
– Handle scrolling, alerts, and more
By doing all of this, you’ll not only have a powerful automation tool for iOS but also the skills to allow you to build upon your knowledge. If you want to continue your learning journey to allow yourself the chance to build something awesome then check out these insights, for all things IT.
Hiep Nguyen, Project Manager