As part of my work giving conference talks about Appium and providing onsite training for organizations, I often encounter creative solutions to common problems people have with Appium. I thought I'd share some of those with you in this blog post. One of the most common questions I get from teams is about how to have one set of tests for both their iOS and Android applications. It's not always possible to share tests between your applications, but if you’d like to give it a try here's my advice.
As part of my work giving conference talks about Appium and providing onsite training for organizations, I often encounter creative solutions to common problems people have with Appium. I thought I'd share some of those with you in this blog post.
Writing Cross-Platform Tests
One of the most common questions I get from teams is about how to have one set of tests for both their iOS and Android applications. It's not always possible to share tests between your applications, but if you’d like to give it a try here's my advice.
Sharing the tests between iOS and Android can be a big win in terms of saving time, but in order to do this there is one big requirement. The scenarios you wish to automate need to flow exactly the same way in both the iOS and Android versions of your application. What I mean is that it will be easiest to write if the user journeys are as identical as possible in each of the two apps. If you abstract your tests to the level of user actions, and then create an implementation of those actions for each platform, you’ll be in good shape.
Imagine a test that looks like this:
Send a message.
Verify the message exists in the sent messages folder.
A test like this is generic enough that you should be able to share test code between the two platforms.
Now imagine a test like this:
Log in with iCloud.
Create a new document and save it.
Verify the document exists to the iCloud Storage.
This test cannot be shared between iOS and Android as there is no way to replicate these steps on an Android test (unless iCloud has added Android support).
It can also be difficult to share a test when the flows are different between applications (e.g., the Android application asks the user to sign up before sending a message, but after allowing a user to view contacts, while the iOS application asks the user to sign up upon launching the app for the first time). In this case, while sharing a test might be possible, it will likely result in messy code and you'll probably be better off keeping them separate.
All this said, if your applications are identical from a UI point-of-view on iOS and Android, then this is all much simpler for you. All you have to do is make sure the accessibility IDs match on the corresponding UI elements in each version of the app, and you can then run the test on both applications. All you'll have to do is make sure your test sets up the appropriate capabilities for each platform. If you are writing an entirely webview-based hybrid app, you may only need to supply the "autoWebView" capability and then the webview automation will kick in on the exact same page, just hosted on two different platforms.
Automating SMS on iOS
A common challenge Appium users face when automating mobile applications is automating SMS messages (especially on iOS). Many apps send verification codes or in other ways require a user to access the content of a text message. Since the Android automation framework supports changing applications, this problem is simple (though perhaps a bit annoying) to solve. On iOS however, we cannot switch applications, so we must be creative.
While I was working with a team in Portugal, they showed me a creative solution to this problem. The gist of it is to set iOS to show SMS messages as alerts. You can change this in the settings. Once the preference is set, you can read the content of all SMS messages using the alerts API as they will appear as UIAlerts in your application.
To set the preference:
Open the "Settings" app.
Choose the "Alerts" option
Additional Useful Capabilities
I've also assembled a collection of some capabilities that you may not know about but can prove extremely useful.
autoWebView - start in the webview context (really useful for Cordova apps)
ignoreUnimportantViews - can speed up your Android tests by trimming out DOM elements that only exist for organizational purposes, thus reducing the depth of the DOM
nativeWebScreenshot - takes the screenshot from UIAutomator instead of chromedriver. This might be of use to you if you are not seeing what you expect in your screenshots.
locationServicesAuthorized - pre-authorizes location services (prevents an alert from showing when you try to use the location of a user)
Auto[Accept|Dismiss]Alerts - useful to prevent alerts interrupting your tests
safariIgnoreFraudWarning - allows https without proper certs. You may find you need this if your test environments don't have a 100% perfect SSL setup
interKeyDelay - time between keystrokes. This may be useful if Appium's speed of typing is causing problems with your app (e.g., extreme race conditions no user should ever encounter)
sendKeyStrategy - (oneByOne, grouped, or setValue) Sometimes, you just need to avoid the keyboard altogether.
A little known feature of Appium is the network conditioning API. This is used to simulate various states of connectivity while running your tests. The complete implementation is only currently available for Android applications, but you may find it quite useful. You can use the driver.setNetworkConnection(value) to do this.
Here's a table of the possible values:
1 (Airplane Mode)
2 (Wifi only)
4 (Data only)
6 (All Network on)
That’s all for this time. I hope you found this post helpful. Feel free to tweet me your own Appium tips and tricks at @thedancuellar on Twitter.