What is the best way to handle iOS and Android in the same code?

If I have to automate the same App in iOS and Android, assume that the app looks almost same in both platforms, what would be the best option to handle both.
I can think of the below options

  1. Take the framework as base and keep separate branches for iOS and Android .
  2. Handle object changes in function level, like if platform is iOS then object is X else if platform is Android then object is Y…etc…
    3.Handle in Framework level. Like …create different classes(pages) for iOS and Android and based on the platform relevant classes will be called

Which is better/Is there a better way than these?
Please let me know your suggestions.

Thanks,
Jerald

3 Likes

I personally like #2 and would use the Decorator Pattern to differentiate between the platforms.

YMMV.

2 Likes

I worked on a project that followed design #2. I think it’s a bad idea. The underlying reason is that iOS and Android are two very different platforms. No matter how hard your team tries to make your iOS app and Anroid app appear and behave the same way, there will inevitably be cases where the two apps will be different, and the number of cases where your apps diverge from each other will only grow with time. I ended up having an if-else branch inside a function where the Android branch was on the order of 100 lines long, while the iOS branch was on the order of 10 lines. A bit further down the flow, the Android branch was a few lines long while the iOS branch was several hundred lines. It was a mess. (It also gets worse if you consider just Android. Samsung Android devices will frequently behave differently from most other Android devices. I have a list of Samsung quirks).

You want to be able to abstract some of those platform-specific details away from your test. If you want an example of how a professional, open source project handles the differences between iOS and Android, look at the Appium project :slight_smile:. The Appium server has separate projects for the iOS and Android drivers. The Java library for Appium also provides a separate Android and IOS driver class as well.

3 Likes

In my experience, we have did this successfully. We written a wrapper for Appium Driver (we called as MobileDriver) and based on the platform we instantiate either the Android Driver or IOSDriver. The end user only gets the MobileDriver.

And moreover, we created two different annotations, @AndroidMobileElement and @IOSMobileElement similar to the PageObject pattern to initialize the locators. During runtime, based on the platform, it will load the required locator either from android or ios annotation.

With this approach, end user has to create one test script which can be executed on both android and iOS, provided both apps have the same flows. In case of different flows, user has to handle with some conditional statements.

We were successful with this approach.

2 Likes

I also use same approach as @email2vimalraj said, so basically in both environment AppiumDriver will work. The flow can be diverted like
if (driver instanceOf AndroidDriver){
// execute AndroidFlow
}else{
// execute IOSFlow
}

And @AndroidFindBy/@IOSFindBy can be mapped to same mobile element
@AndroidFindBy()
@IOSFindBy()
private MobileElement loginButton;

But at other point i also agree with @afwang, it will be complete mess. You need to use this approach wise fully. As long as your automation keep adding multiple scenarios this will become very difficult to handle.

4 Likes

So almost for 1 year , I tried following the approach as in #2. I used a if_ios =TRUE to handle platform specific code.
However, over time the ios and Android apps were growing feature different to meet business needs. And it kept adding more conditionals for Appium tests.
My solution now, is to keep both tests in separate repo. They had same baseline, keeping them separate makes code more clean and easy to maintain\update.

1 Like

Thanks Vimal!
In one of my project, we had a wrapper class as base class which will provide one driver based on the platform. I understand the object identification too.
But when we add more and more scenarios, we had to add more and more conditions in terms of functional flows. Haven’t you come across such issues?

Thanks,
Jerald

MSid,
yeah…that is the easy way. But how do you maintain parity between those 2 repos especially when separate persons handle iOS and Android? If it is the same person, then it is easy to maintain parity.

Thanks,
Jerald

@jervinjn: Till now, we haven’t faced any issue.
Only thing as a test framework team, we ensure what methods are supported for android / ios and what not. So we throw an exception when user is accessing unsupported method for a device type. Yes it needs some effort from the framework team, but seems worth the effort.

Till now its only me doing it , so we haven’t run in this issue. I would rather follow the same flow as development planning

Hi Guys,
Can you please share sample code repo for better understanding?

Hi Vimal,Thank you very much.Could you please let me know if its possible to send me code snippet on how did you handle this?