Mobile Testing Guide
Testing Framework Comparison
| Framework | Platform | Language | Best For |
|---|---|---|---|
| Detox | React Native (iOS + Android) | JavaScript | Gray-box RN E2E; fast, stable |
| Appium | iOS + Android + Web | JS/Python/Java/Ruby | Cross-platform E2E, black-box, real devices |
| XCTest + XCUITest | iOS only | Swift/Objective-C | Native iOS unit + UI tests |
| Espresso | Android only | Java/Kotlin | Native Android UI tests, fast in-process |
| Flutter Test | Flutter (cross-platform) | Dart | Flutter widget tests + integration tests |
| Maestro | iOS + Android | YAML flows | Simple E2E flows without coding |
Detox E2E Test (React Native)
// e2e/login.test.js
describe('Login Flow', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should show dashboard after successful login', async () => {
await element(by.id('email-input')).typeText('[email protected]');
await element(by.id('password-input')).typeText('password123');
await element(by.id('login-button')).tap();
await waitFor(element(by.id('dashboard-screen')))
.toBeVisible()
.withTimeout(5000);
await expect(element(by.text('Welcome back'))).toBeVisible();
});
it('should show error for wrong credentials', async () => {
await element(by.id('email-input')).typeText('[email protected]');
await element(by.id('password-input')).typeText('wrong');
await element(by.id('login-button')).tap();
await expect(element(by.id('error-message'))).toBeVisible();
await expect(element(by.text('Invalid credentials'))).toBeVisible();
});
});
// package.json
// "detox": {
// "devices": {
// "simulator": { "type": "ios.simulator",
// "device": { "type": "iPhone 14" } }
// },
// "apps": { "ios": { "binaryPath": "ios/build/app.app" } },
// "configurations": {
// "ios.sim.release": {
// "device": "simulator", "app": "ios" }
// }
// }
Mobile Testing Checklist
| Area | Test Cases |
|---|---|
| Network conditions | Offline, slow 3G (Charles Proxy / Android emulator network settings) |
| Interruptions | Incoming call, push notification, app backgrounded |
| Device variations | Different screen sizes, notch, dynamic island, font size accessibility |
| OS versions | Latest + latest-1 + oldest supported version |
| Permissions | First-time permission requests, denied permissions (camera, location) |
| Deep links | Universal links, custom URL schemes open correct screen |
| Memory pressure | Low-memory scenarios, background kill and restore |
| Orientation | Portrait โ landscape transition preserves state |