5. Challenges
• Maintain App state in failure
• Complex app flows
• Multiple App States
• Test in multiple environments
• Multiple Test Data Variations
• Complex/Secured back end systems
• Testing in multitude of devices
7. #1 Maintain App State in
Android Failure
Android - start activity to launch the screen
Activity activity = new Activity(appPackage,appActivity);
activity.setAppWaitPackage(appPackage);
activity.setAppWaitActivity(appWaitActivity);
activity.setStopApp(false);
testdriver.startactivity(activity);
8. #2 Complex App Flows
SSO Jump
Handle SSO jump from native to browser and vice versa ?
• Android - Back Key event
• iOS - Scheme name in browser:
driver.getKeyboard.sendKeys(scheme+”://n”);
9. #2 Complex App Flows
Switch Native <—> Settings
Need of AUT settings in Phone Settings app
• Process Argument Capability - allows to pass command line
arguments, environment variables to AUT
List<String> pArgs = new ArrayList<>();
pArgs.add(“AutomatedTestConfigEnabled”);
pArgs.add(“environment.selected=container.+env);
if(getSystemParameter(“TEST_ANYWHERE”).equalsIgnoreCase(“true”))
pArgs.add(“container.useanywhere=YES”);
Capabilities.setCapability(IOSMobileCapabilityType.PROCESS_ARGUMENTS,
pArgs);
10. #3 Multiple App State
• Behaviour of application changes based on the verified or
non-verified user account (e.g: OTP verification)
• Multiple run of same tests or previous run of same test
could cause the state change in the application.
11. #3 Multiple App State
Solution: JAVA Rest Client Library
• Opens up HTTP connection
• setHeader
• setRequestBody
• Get , Put, Post, Delete
• getResponse
• getStatusCode
12. #4 Multi-Test Environment
• Need to support same tests against multiple environment
• Multi environment —> Test Data varies
13. #4 Test Data Variations
Master Card Visa card Debit Card Gold Card
Diamond Card Platinum Card
EveryDay Account Savings Account HL Account
14. #4 Data Driven Testing
• Static Data - TestNG
• @Parameter annotation
• @Dataprovider annotation
• Custom getData from xls
• CQ5 Dynamic Data - JAVA Rest Client
• Rest API - JSON Response
15. #5 Complex Backend
• Multiple downstream back end channels
• Update via Rest API - corrupts the test data
• E.G: Card activation flow - one time activity (Burnable
data)
16. #5 Burnable Data
API Mock Server - node js server
• Stubbed req & response
• Usage of mock server
• Creation of different rules based on specific input
20. Emulators/Simulators
Challenges
• Emulator launch for every fresh run
• Parallel emulator runs slows down the performance
• iOS Simulators cannot be run in parallel (older versions)
• Advance interactions behaves differently in physical
device and emulators.
22. MDC - deviceBridge
• Device Bridge is a software application - .exe / .dmg
• Connect to MDC server with ip address and credentials
• Acquire devices - connects the device to your machine
• Appium can identify the above connected devices
23. Selenium Grid + MDC
Team City
Selenium Grid
VM1 VM2 MacMini MacMini Device Bridge
Hi Guys,
Good Morning everyone !
Hope you all having great time here in Conference.
Let me introduce myself, I am Pavithra Navaneeth - Test automation lead and automation specialist working for Banking space in Sydney, Australia.
So today I am going to deliver the talk on “Appium in an Enterprise organisation”
Here is our today’s agenda:
Ill start with ‘Intro about Mobile Banking’
Then comes with Challenges we face in an enterprise banking automation
Solutions for the same.
Our CI journey and CI implementation.
If you think of banking, there are n number of services provided by banking in general such as checking your account information, transactions, money transfers, trading, account security, online shopping, different kind of payments, investments, customer support, content services etc…
Previously all these were managed separately and some of the services were provided through online (especially web) and some services were provided in branch. But now in digital era everything has to be digitalised and everything can be achieved via one single application in your mobile.
Achieving UI automation for such application is not so easy. Especially when this application has to be tested in both android & iOS - Appium is the best choice - open source tool for automating such applications.
Here for Mobile UI automation we used the following set of tools.
Its Appium - based on Java client library
TestNG as the Testing framework
Maven - as project build tool.
Lets start with the challenges. These are the some of the top challenges we faced w.r.t banking automation. Go - through it
Some of these challenges are specific to any native app tied up with Appium and some of it are related specifically to banking.
Let me start with few generic ones.
First one is Maintain app state during failure
Say there is a scenario which we have to test for payment transaction and if the transaction has failed due to some reason
As you all know if there is failure in the test in-between, it doesn’t reach the end state which in-turn doesn’t allow the next test to start
In case of browser, we usually refresh the browser or directly navigate to the URL, however in case of native we cannot refresh the app. Instead we have to kill and start the app again.
But there is a problem in doing this especially while running the test in CI runs e.g in grid node. Appium nodes in grid are often set with full reset ⛳️ to always ensure the clean state of the run and also to fresh install the new version of the app everytime.
So, in this case - to restart the app if we use driver.reset or driver.close/quit and launch - it would uninstall the app and install the app which is time consuming and once again we have to run user registration (especially in banking app it involves registration, OTP verification , setting up authentication, etc.. before reaching the actual test) - this is very time consuming. Hence what we do here - we pass enableAppResetart parameter to the driver launch method, and if enableAppRestart is true, set the noReset capability to true. Remaining capabalities remain intact and driver session gets started with no reset capability thus in turn restarts the app maintaining the same state.
How do I maintain app states especially in case of failure? In browser it is easy to load the url or refresh the page, but app cannot be refreshed without killing the app. How to restart the app in CI execution where Appium node is running with full reset flag as true. driver.reset, driver.close, driver.launch cannot be used here as these works as expected only when no reset flag is set to true.
Next comes the Complex app flows, there are n number of complex app flows in any application, but here I hast just chose one specific flow which is common for any kind of native app. ie. SSO Jump
SSO is basically single sing on - if you tap on any of the link in the native app - for e.g: My details in the banking application it deep links to the corresponding browser page.
We don’t have to perform specific step to navigate to the browser here - just by a tap it navigates to the browser already. You can perform navigations or assertions in the browser page with usual commands and verifications. But how do we navigate back to the native app?
In case of android - it is much easier we can invoke the back key event and it can navigate back to the application.
In case of iOS - it is not easy - there is no back button in iOS and there is no direct Appium command available to navigate back to the native.
So we use something called scheme name. Every iOS native application will have a scheme name defined - usually testers won’t be aware of this. Ask your developer for your app scheme name.
If we type in the scheme name in the browser url field followed by :// -it actually launches the corresponding application. For e.g: if you type sms:// in your iPhone safari it would popup the message asking whether you want to open the message app and by tapping on open it loads the message app. You can even try manually. So similarly we can type in our application scheme name in browser and it goes back to the native.
We can switch between apps mainly by creating another driver session with different capabilities.
How do we do this in CI environment especially when Appium node and capabilities are set with full reset flag.
Because, when full reset flag is on - driver.launch uninstalls the app and installs the app freshly.
First driver session is my test app. Before creating settings driver session I need to first do driver.quit which uninstalls the app. Thus when I launch settings it doesn’t have the context of my test app.
Define with example such as -
E.G.1: Without OTP verification, payment to third party cannot be completed. How to get OTP in test environment - via WebService API or SMS gateway portal in Test environment. This needs to be contacted in between the test run.
E.G:2: Bill pay test. Pay to biller is one of scenario, If my test scenario is to create the recurring payment for different frequency of time - previous run or multiple run of the same test impacts my next run. So there should be pre or post requisite to delete these recurring payments. Main aim of the test is to create recurring payment but if pre or post requisite (UI navigations are with longer navigations) it impacts execution time and performance.
Instead of having UI navigations as pre-post req and in order to fetch data from ; it can be wrapped up in REST API calls.
To solve above requirements - we introduced the RestClient library in the framework which opens up the http connection for different web-services needs. It got certain wrapper methods which helps to send the request and get response in API call.
Explain the complexity involved in banking test environment and why multiple dev, test regions are required. E.G: T1 could be test region for prod backend version. T2 could be test region of current backend version (n+1 - where ongoing backend development changes are deployed).
N number of legacy back end systems involved, change in one backend system could impact multiple applications in multiple channels; hence end to end testing needs to be carried out for all the end user applications. State with one example of back end system.
There is a need for multiple test data variations for single test scenario. E.G: Verify different kind of accounts, change card settings for different kind of cards.
This is where need of TestNG comes, we use @Parameter annotation to pass in specifically the environment name and some of the master data. And use @Dataprovider annotation which uses custom method to parse the xls data and returns the array object and in turn passed as test data arguments to the test methods.
If data dynamically varies (content from CQ5) - Here we also use Rest API calls and the JSON response serves as the data for these verifications.
Some of the flows are not just done only with back end calls. For e.g: Card activation - Once card is activated it not just updates in the native back end, it gets updated in n number of downstream channels. There are different batch jobs scheduled on daily basis which fetches the data, process and updates in different systems.
So even though I have these API calls in pre-post request, there are few flows that cannot be reverted or updated end to end.
Burnable data is the data which is once used cannot be used again. E.G: In terms of banking, if you ordered for a new credit card and first time you can activate the card through native app. Same card number (test data) cannot be reused again for card activation again.
These specific tests are set against the mock server instead of live test region. Solves the burnable data issue. Even regular acceptance or regression test data (API flows) are stubbed in the mock server and UI tests are run against the mock server so that it can be used to test against native - develop builds and also when test environment goes down or under maintenance.
While stubbing the regular flows, we also have to ensure to test both happy/unhappy paths. To test error or unhappy paths we create rules based on specific input. E.G: if login pin is 1234 - response should be X, if login pin is 3456 - response should be Y etc..
Such cases we pass these inputs (login pin) as parameter in TestNG parameter or data provider and based on these test flow changes.
Though Android & iOS are the most popular and widely used models, there are n number of variations in each of these device types. I think, in this forum I don’t need to explain the need of testing in multitudes of devices. Nowadays if we purchase a license automation tool it comes along with the cloud executions based on your requirement. But in case of Appium used as open source; we either have to rely on cloud labs such as sauce lab or own in house set of devices.
This is the normal CI process which everyone knows. When we say CI in testing, it means remote test executions. In a banking organisation, security plays a vital role, it is not easy to get your functional or backend tests in the cloud execution even though you got enough funding.
Cabinet cart maintained by operations team with set of devices.
Initially it was purchased mainly for manual execution (before automation came into picture).
We wanted to POC same solution for automation execution.
MDC comes with device portal where one can reserve the device, connect the device remotely and perform testing directly through portal.
adb devices - list the connected android devices
Instruments -s devices - list the connected iOS devices
Note: With Mobile labs version, they provide in built support for Appium server. There is no specific need to start the Appium server but we haven’t tried out the version yet. Prior to this feature, we were in need of making this solution available for CI executions.
We tried integrating MDC with Selenium Grid and it was a great success.
In a nutshell, to achieve full fledge automation in an enterprise organisation - there are many bits and pieces which needs to be integrated carefully in a organised manner and need to be maintained.
Above are not just the challenges we faced, we have few more challenges which are still need to be addressed and some doesn’t have a solution yet. So, its a long way to go.