Appiumproworkshoptvm 190519172551
Appiumproworkshoptvm 190519172551
Syam Sasi
Martin Schneider
https://github.com/martinschneider/appium-workshop-2019-05-18
2011: Dan Cuellar creates iOSAuto, a tool for iOS automation written in C#
2012: Dan presents Appium during a Lightning Talk at the 2012 Selenium Conference in London
2012: Dan rewrites appium in Python and open-sources it under the Apache 2 license
2012: Cooperation with Jason Huggins (Selenium co-founder) starts
2013: Saucelabs starts backing Appium
2013: Appium is rewritten using node.js
2013: Android support is added → first truly platform-independent mobile testing framework
2014: Appium 1.0 is released
2016: Drivers for Windows desktop and youi.tv automation are added
2016: Appium is donated to the JS Foundation
http://appium.io/history.html
https://github.com/appium
http://appium.io/
© Martin Schneider, mart.schneider@gmail.com
Coffee break reading material ;-)
https://www.infoq.com/news/2018/04/cucumber
-bdd-ten-years
https://www.seleniumhq.org/about/history.jsp
http://appium.io/history.html
1. You shouldn't have to recompile your app or modify it in any way in order to
automate it.
to automation APIs.
JSONWP
tor2
XC
ma UIT
I Auto es
t
● Client-server architecture U
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/CounterTest01.java
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/CounterTest02.java
Appium capabilities
Appium Capabilities
General Capabilities
newCommandTimeout - in seconds
Appium Desktop
Why Appium Desktop?
{
"platformName":"android",
"deviceName":"Pixel",
"automationName":"UiAutomator2",
"app":"/path/to/apk/file",
"avd","Pixel"
}
Android locator types
Android locator types
● accessibility
● id
● xpath
● class
● uiAutomator
● image
http://appium.io/docs/en/commands/element/find-elements/
https://saucelabs.com/blog/advanced-locator-strategies
Android locator types
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/CounterTest03.java
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/CounterTest04.java
Inspector tools
Appium inspector
{
"platformName" : "android",
"appPackage" : "com.thecarousell.Carousell" ,
"appActivity" : "com.thecarousell.Carousell.activities.EntryActivity" ,
"appPath": "/Users/martinschneider/carousell.apk",
"deviceName" : "test",
}
Appium inspector
Macaca inspector
● https://macacajs.github.io/app-inspector/
● npm i app-inspector -g
● adb devices
● app-inspector -u YOUR-DEVICE-ID
● http://10.0.1.117:5678
● Does not require Appium or an Appium session
Macaca inspector
● https://macacajs.github.io/app-inspector/
● npm i app-inspector -g
● app-inspector -u YOUR-DEVICE-ID
● http://10.0.1.117:5678/
Waiting strategies
Waiting strategies
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/LoginTest01.java
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/LoginTest02.java
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/LoginTest03.java
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/LoginTest04.java
Static wait
Thread.sleep(3000);
driver.manage().timeouts().implicitlyWait(10,
TimeUnit.SECONDS);
● Speeds up test execution locally but also slows down overall test execution
because it is a global setting (no ability to fail fast)!
● Better than static waits but still not quite convenient enough….
1. Touch Action
*press*release*moveTo*tap*wait*longPress.cancel.perform
TouchAction().press(el1).moveTo(el2).release();
2. Multi Touch
action1 = TouchAction().tap(el1);
action2 = TouchAction().tap(el2);
MultiAction().add(action1).add(action2).perform();
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/swipe/SwipeTest.java
Page object model
Page objects
● De-facto standard design pattern in UI test automation.
● Tests don’t care about the layout and locators of your app. They just
interact with page objects.
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/LoginTest05.java
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/LoginTest06.java
● /appium-demo/src/test/java/io/github/martinschneider/appium/android/LoginTest07.java
How to design a test framework?
Some thoughts
How to design a test framework?
● Don’t re-invent the wheel but combine existing tools in a way that best fit
your use-case.
● Always keep re-usability, adaptability, extensibility and scalability in mind.
● A quick (and “dirty”) PoC is a start but what’s your use-case in 6 months / 1
year / 5 years… Is your design ready for the change?
● → Have a vision and lay the foundation accordingly.
● Good design now = less refactoring later.
● Test automation requires software engineers (test engineer = engineer).
● Apply the same (or better) practices you have for building the solutions you
sell to your customers, always lead by example (quality!).
● Powerful under the hood but super-easy to use.
● A framework is cool but don’t forget the culture in which it is used.
https://www.linkedin.com/in/martin-schneider
Tests Testdata
Robot
Test helper
API layer
IOS automation
Locator Strategy for iOS
Accessibility ID
driver.findElement (MobileBy.AccessibilityID ("foo"));
iOS NS Predicates
driver.findElementByIosNsPredicate (tableViews ()[1].cells().firstWithPr
edicate("label == 'Olivia' " ));
● /appium-demo/src/test/java/io/github/martinschneider/appium/ios/IOSTest.java
Real device vs. simulators/emulators
Appium On Real Devices - Android
https://developer.android.com/studio/debug/dev-options
1. cd
/usr/local/lib/node_modules/appium/node_modules/appium-
xcuitest-driver/WebDriverAgent
2. mkdir -p Resources/WebDriverAgent.bundle
3. /bin/bash ./Scripts/bootstrap.sh -d
4. brew install carthage
5. brew install libimobiledevice --HEAD
6. npm install -g ios-deploy
7. UI Automation enabled on iOS device
8. Xcode has proper code sign enabled
http://appium.io/docs/en/drivers/ios-xcuitest-real-devices/
© Martin Schneider, mart.schneider@gmail.com
Which one I need?
capabilities.setCapability("app", appUrl);
new AppiumDriver("http://cloud.com/wd/hub", capabilities);
● In the US Apple and Samsung cover 81% of the market (UK 87%,
Singapore 82%, Australia 89% etc.)
Source: https://deviceatlas.com/
© Martin Schneider, mart.schneider@gmail.com
Device models
● Huawei (13,3%)
surpassed Apple
(11,9%) in market
share in Q2/2018
Market specifics
● India: 20% Xiaomi (#3) = 2/3 are neither Apple nor Samsung
● Myanmar (2018): 19% Oppo (#2), 18% Vivo (#3), 13% Xiaomi (#4), 11%
Huawei (#5) = 70% not Apple and Samsung
● Pakistan: 11% QMobile (#2)
● Bangladesh: 14% Symphony (#2)
Sources:
https://www.gartner.com/en/newsroom/press-releases/2018-08-28-gartner-says-huawei-secured-no-2-
worldwide-smartphone-vendor-spot-surpassing-apple-in-second-quarter, https://deviceatlas.com/
● AWS Device Farm doesn't have any Huawei, Xiaomi, Oppo or Vivo models
(in their public cloud)
● Browserstack only supports Samsung, Google and Apple phones (and one
OnePlus model)
Sources:
https://www.gartner.com/en/newsroom/press-releases/2018-08-28-gartner-says-huawei-secured-no-2-
worldwide-smartphone-vendor-spot-surpassing-apple-in-second-quarter, https://deviceatlas.com,
https://www.browserstack.com/list-of-browsers-and-platforms/app_automate, http://awsdevicefarm.info
We will run the same login test on AWS Devicefarm, Browserstack and locally.
AWS Devicefarm
● package the test configuration into a test spec and upload to AWS
● upload the APK file to AWS
● package our tests (+framework) and upload to AWS
● select an available device (using device filters)
● execute the tests and process the results
Browserstack
● upload the APK file to Browserstack
● configure the execution (this includes the device selection) using Capabilities
● execute the tests and process the results
www.justtestlah.qa
https://medium.com/@mart.schneider/mobile-test-automation-using-aws-device-farm-6bcf825fa27d
© Martin Schneider, mart.schneider@gmail.com
Appium tips and tricks
#1 Network Conditions
● Send SMS -
driver.sendSMS("555-123-4567", "Hey?");
● GSM Call -
driver.makeGsmCall("5551234567", GsmCallActions.CALL);
● GSM Signal -
driver.setGsmSignalStrength(GsmSignalStrength.GOOD);
● Geo Location -
driver.setLocation(new Location(49, 123, 10));
#3 Dealing With An Element When Visibility Is False
// first, find our element
WebElement ref = wait
.until(ExpectedConditions .presenceOfElementLocated (element));
// get the location and dimensions of the reference element, and find its
center point
Rectangle rect = ref.getRect();
int refElMidX = rect.getX() + rect.getWidth() / 2;
int refElMidY = rect.getY() + rect.getHeight() / 2;
● Deeplinks
● OptionalIntentArguments
caps.setCapability("optionalInentArguments", String.format("-e \"username\"
\"%s\" -e \"password\" \"%s\"", AUTH_USER, AUTH_PASS));
#5 Fine Tuning The Capabilities - Cross Platform
● Cross Platform
○ noReset
○ fullReset
○ isHeadless
#6 Fine Tuning The Capabilities - Android
● Android
○ disableAndroidWatchers
○ autoGrantPermissions
○ skipUnlock
○ ignoreUnimportantViews
#7 Fine Tuning The Capabilities - iOS
● iOS
○ usePrebuildWDA and derivedDataPath
○ useJSONSource
○ iosInstallPause
○ maxTypingFrequency
○ realDeviceScreenShotter
○ simpleIsVisibleCheck
#8 Testing App Upgrades
Android
driver.installApp ("/path/to/apk" );
driver.startActivity (activity);
iOS
HashMap<String, String> bundleArgs = new HashMap<>();
bundleArgs .put("bundleId" , BUNDLE_ID );
driver.executeScript ("mobile: terminateApp" , bundleArgs );
HashMap<String, String> installArgs = new HashMap<>();
installArgs .put("app", appUpgradeVersion );
driver.executeScript ("mobile: installApp" , installArgs );
driver.executeScript ("mobile: launchApp" , bundleArgs );
#9 Switching Between Apps
● Android
driver.startActivity (settingsAppPackageName , settingsAppActivityName );
● iOS
// launch the photos app (with the special bundle id seen below)
HashMap<String, Object> args = new HashMap<>();
args.put("bundleId" , "com.apple.mobileslideshow" );
driver.executeScript ("mobile: launchApp" , args);
1. Using SendKeys
pickerWheelElement.sendKeys("March");
IOSStartScreenRecordingOptions
iOSStartScreenRecordingOptions =new
IOSStartScreenRecordingOptions().withVideoQuality(IOSStartSc
reenRecordingOptions.VideoQuality.HIGH).withTimeLimit(Durati
on.ofSeconds(SCREEN_RECORD_DURATION));
driver.startRecordingScreen(iOSStartScreenRecordingOptions);
record = ((IOSDriver) driver).stopRecordingScreen();
byte[] decode = Base64.getDecoder().decode(record);
File videoFile =new File(new
StringBuilder().append(“MyVideo.Mp4”).toString());
FileUtils.writeByteArrayToFile(videoFile, decode);
#14 Parallel And Distributed Testing
● Running multiple Appium servers, and sending one session to each server
● Running one or more Appium servers behind the Selenium Grid Hub, and
sending all sessions to the Grid Hub
● WinAppDriver - https://github.com/Microsoft/WinAppDriver
Quiz Time
Go to https://kahoot.it
References
● http://appium.io
● https://appiumpro.com/editions
● https://github.com/SrinivasanTarget/awesome-appium
● https://github.com/appium/appium/tree/master/docs/en/advanced-concepts
● https://github.com/singapore-appium-meetup/meetups
● https://www.justtestlah.qa