Master mobile test automation for iOS and Android with modern tools and cloud platforms
Mobile testing is like testing a car in different weather conditions - you need to check how your app works on different devices, screen sizes, and operating systems.
Native App Testing
Apps built for specific platforms (Swift/Kotlin)
Hybrid App Testing
Web apps wrapped in native container (Ionic, Cordova)
Cross-Platform Testing
React Native, Flutter apps
Mobile Web Testing
Websites accessed via mobile browsers
Appium is like a universal remote control for mobile apps - it works with iOS, Android, and even Windows apps!
# Install Appium
npm install -g appium
# Install drivers
appium driver install uiautomator2 # Android
appium driver install xcuitest # iOS
# Start Appium server
appium
# Install client library
npm install webdriverio @wdio/cli
// wdio.conf.js - Android configuration
exports.config = {
capabilities: [{
platformName: 'Android',
platformVersion: '13',
deviceName: 'Android Emulator',
app: './app/android/app-debug.apk',
automationName: 'UiAutomator2',
appPackage: 'com.example.app',
appActivity: '.MainActivity'
}]
}
// wdio.conf.js - iOS configuration
exports.config = {
capabilities: [{
platformName: 'iOS',
platformVersion: '16.0',
deviceName: 'iPhone 14',
app: './app/ios/MyApp.app',
automationName: 'XCUITest',
bundleId: 'com.example.app'
}]
}
// Accessibility ID (Best practice)
await $('~login-button').click();
// XPath (Android)
await $('//android.widget.Button[@text="Login"]').click();
// iOS Predicate
await $('-ios predicate string:name => "Login"').click();
// Class name
await $('android.widget.EditText').setValue('test@email.com');
// Resource ID (Android)
await $('android=new UiSelector().resourceId("com.app:id/username")');
// iOS Class Chain
await $('-ios class chain:**/XCUIElementTypeButton[`name => "Login"`]');
Mobile apps use touch gestures - tap, swipe, pinch, long press. Let's automate them all!
// Tap
await $('~button').click();
// Long press
await $('~element').touchAction([
{ action: 'press', x: 100, y: 200 },
{ action: 'wait', ms: 1000 },
{ action: 'release' }
]);
// Swipe down (scroll)
await driver.touchAction([
{ action: 'press', x: 200, y: 800 },
{ action: 'wait', ms: 200 },
{ action: 'moveTo', x: 200, y: 200 },
{ action: 'release' }
]);
// Pinch zoom
await driver.execute('mobile: pinch', {
scale: 2.0,
velocity: 1.0
});
// Drag and drop
const source = await $('~source-element');
const target = await $('~target-element');
await source.dragAndDrop(target);
Detox is specifically built for React Native - faster and more reliable than Appium for RN apps.
# Install Detox
npm install detox --save-dev
detox init
// e2e/firstTest.e2e.js
describe('Login Flow', () => {
beforeAll(async () => {
await device.launchApp();
});
it('should login successfully', async () => {
// Type into fields
await element(by.id('email-input'))
.typeText('test@email.com');
await element(by.id('password-input'))
.typeText('password123');
// Tap button
await element(by.id('login-button')).tap();
// Verify navigation
await expect(element(by.text('Welcome')))
.toBeVisible();
});
});
# Run tests
detox test --configuration ios.sim.debug
Test websites on mobile browsers - Chrome, Safari, Firefox mobile.
// Mobile Chrome
capabilities: {
platformName: 'Android',
browserName: 'Chrome',
deviceName: 'Android Emulator'
}
// Mobile Safari
capabilities: {
platformName: 'iOS',
browserName: 'Safari',
deviceName: 'iPhone 14'
}
// Test mobile website
describe('Mobile Web', () => {
it('should work on mobile', async () => {
await browser.url('https://example.com');
await $('button').click();
await expect($('h1')).toHaveText('Welcome');
});
});
Test on real devices without buying them! Cloud platforms provide access to 1000s of devices.
BrowserStack
3000+ real devices, live testing, automation
Sauce Labs
Real devices, emulators, CI/CD integration
AWS Device Farm
Amazon's device testing service
LambdaTest
3000+ browsers and devices
// wdio.conf.js
exports.config = {
user: process.env.BROWSERSTACK_USERNAME,
key: process.env.BROWSERSTACK_ACCESS_KEY,
hostname: 'hub.browserstack.com',
capabilities: [{
device: 'Samsung Galaxy S23',
os_version: '13.0',
app: 'bs://your-app-id',
'browserstack.debug': true,
'browserstack.networkLogs': true
}]
}
Write tests once, run on both iOS and Android - the dream of every QA engineer!
// helpers/selectors.js
const isIOS = driver.isIOS;
const selectors = {
loginButton: isIOS
? '~login-button'
: 'android=new UiSelector().resourceId("login-button")',
emailInput: isIOS
? '-ios predicate string:name => "email"'
: '//android.widget.EditText[@resource-id="email"]'
};
// Use in tests
await $(selectors.emailInput).setValue('test@email.com');
await $(selectors.loginButton).click();
Build a comprehensive test suite for a shopping app with login, browse, cart, and checkout.
// test/specs/shopping.e2e.js
describe('Shopping App E2E', () => {
it('complete purchase flow', async () => {
// 1. Login
await $('~email-input').setValue('test@email.com');
await $('~password-input').setValue('password123');
await $('~login-button').click();
// 2. Browse products
await expect($('~products-list')).toBeDisplayed();
// 3. Add to cart
await $('~product-1').click();
await $('~add-to-cart-button').click();
await driver.back();
// 4. Go to cart
await $('~cart-icon').click();
await expect($('~cart-item')).toBeDisplayed();
// 5. Checkout
await $('~checkout-button').click();
await $('~confirm-order-button').click();
// 6. Verify success
await expect($('~order-success')).toBeDisplayed();
});
});
You've mastered mobile test automation:
Next: CI/CD Integration & Test Management in Module 6!