Skip to main content

Cross-Platform Strategy: Android and iOS

One of the most common questions in mobile test automation is: should Android and iOS tests live in the same project or in separate projects? The answer depends on how similar the apps are.


Same Project: When and Why​

Combine both platforms in a single project when:

  • The Android and iOS apps share the same user flows and screens.
  • The business logic and test scenarios are identical across platforms.
  • You want to maximize code reuse for test logic, utilities, and data.

How It Works​

Keep your test logic in shared classes and isolate platform differences in the page object locators:

LoginPage.java
import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import com.shaft.driver.SHAFT;

public class LoginPage {
private final SHAFT.GUI.WebDriver driver;

public LoginPage(SHAFT.GUI.WebDriver driver) {
this.driver = driver;
}

// Platform-specific locators
private By getUsernameInput() {
return isAndroid()
? By.id("com.example:id/username")
: By.name("username_field");
}

private By getPasswordInput() {
return isAndroid()
? By.id("com.example:id/password")
: By.name("password_field");
}

private By getLoginButton() {
return isAndroid()
? By.id("com.example:id/login_btn")
: By.xpath("//XCUIElementTypeButton[@name='Login']");
}

// Shared test logic
public void login(String username, String password) {
driver.element()
.type(getUsernameInput(), username)
.and().type(getPasswordInput(), password)
.and().click(getLoginButton());
}

private boolean isAndroid() {
return SHAFT.Properties.platform.targetPlatform()
.equals(Platform.ANDROID.name());
}
}

Your test class stays completely platform-agnostic:

LoginTest.java
@Test(description = "Verify successful login")
public void testLogin() {
new LoginPage(driver).login("user@example.com", "password123");
// Validations work the same way on both platforms
}
tip

Switch platforms by changing a single property — no code changes needed:

src/main/resources/properties/custom.properties
targetOperatingSystem=ANDROID

Or override it from the command line:

mvn test -DtargetOperatingSystem=IOS

Separate Projects: When and Why​

Use separate projects when:

  • The Android and iOS apps have significantly different UIs, flows, or features.
  • Each platform has unique screens or interactions that the other does not have.
  • The teams maintaining Android and iOS tests are different and work independently.
  • You need different dependency versions or build configurations for each platform.

Shared Utilities as a Library​

Even with separate projects, you can share common utilities (API clients, data generators, helper methods) by extracting them into a shared Maven/Gradle module:

my-company-tests/
├── shared-utils/ ← Common utilities module
│ └── src/main/java/
├── android-tests/ ← Android test project
│ └── pom.xml (depends on shared-utils)
└── ios-tests/ ← iOS test project
└── pom.xml (depends on shared-utils)

Decision Guide​

FactorSame ProjectSeparate Projects
Identical user flows✅ Best fitOverhead
Different UIs per platformComplexity✅ Best fit
Shared test logic✅ Maximum reusePartial (via shared library)
Independent team ownershipCoordination needed✅ Best fit
CI/CD simplicity✅ One pipeline, parameterizedTwo pipelines

For most teams, starting with a single project is the best default. You get maximum code reuse and a single source of truth for your test scenarios. If the apps diverge significantly over time, you can always split later.

info

SHAFT Engine's property-based platform switching makes it easy to run the same tests against both platforms from a single project. Just parameterize targetOperatingSystem in your CI/CD pipeline.