Q18 of 26 · Mobile QA
How do you design a cross-platform mobile test suite that shares logic between iOS and Android?
Short answer
Short answer: Abstract platform divergence — locators and driver-specific commands — inside screen object classes. Test cases call screen objects with platform-neutral method names; the screen object implementation selects the right locator or execute command based on the current platform at runtime.
Detail
The fundamental rule: test cases should not contain any string that differs between platforms. All platform divergence lives inside screen objects.
Architecture:
- A
BasePageorBaseScreenclass holds the driver reference and shared utilities —waitForElement,scrollToElement, aplatformgetter. - Each screen has a single class. Locators are defined as getters that switch on
this.platform:get loginButton() { return this.platform === 'iOS' ? $('~Login') : $('~login-btn'); } - For platform-specific actions (face ID prompt, Android back button), expose them as methods on the base class that branch internally.
Configuration layer: a factory or test config determines which AppiumDriver capabilities to load — one JSON file per platform. The test runner picks the right config via an environment variable (PLATFORM=ios npm test).
What this achieves: the same test file (test/flows/checkout.test.ts) runs unchanged on both platforms. Adding a new platform means adding new screen object implementations — not touching test logic. When a locator changes on Android, you update one getter in one screen object class.
Where this breaks: deeply different UX between platforms. If the checkout flow has a fundamentally different step order on iOS vs Android, you need platform-specific test logic. Acknowledge that in the design and put it in a separate platform-specific test file rather than trying to unify everything.