Upload
globallogic-ukraine
View
511
Download
5
Embed Size (px)
DESCRIPTION
This is a presentation about mobile apps testing using Appium. The presentation conrtains tips on comprehensive testing of apps written for various devices and platforms. Presentation by Yaroslav Pernerovskyy (Lead Test Engineer, GlobalLogic, Kyiv), delivered at UA Mobile, November 22, 2014. More details - http://uamobile.org
Citation preview
Cross platform Appium tests
How To
Who?
Yaroslav Pernerovskyy
• Test Automation Lead in Global Logic
y.pernerovskyy
www.linkedin.com/pub/yaroslav-pernerovsky/1/9b5/55
What?
Why?
• Web application
• Selenium based test framework (Java)
• iOS and Android clients
• Reuse framework features for mobile
• Open Source (Free of charge)
• Easy setup and configuration
• Scalable and flexible
Appium Rules
• Test the same app you submit to the marketplace
• Write your tests in any language, using any framework
• Use a standard automation specification and API
• Build a large and thriving open-source community effort
http://appium.io/slate/en/master/?ruby#appium-philosophy
iOSAndroid
Firefox OSTest Script
JSON Wire protocol
How it works
Native automation instruments
Remote Web Driver
node.js
UiAutomator
Selendroid
Instruments
Marionette
Features
• Native automation instruments – Android: UiAutomator (4.2), Selendroid (2.3)
– iOS: UIAutomation
– Firefox OS: Marionette
• Emulators/simulators and real devices
• Web Driver API
• Selenium Grid
• Ruby, Python, Java, JavaScript, PHP, C#...
• Documentation
• http://appium.io/
Install
• npm install -g appium
• Appium.dmg
• Appium.exe• https://bitbucket.org/appium/appium.app/downloads/
Appium GUI
Command line
appium -a 192.168.10.11 -p 4723
--device-name "iPad Simulator" --force-ipad
--orientation LANDSCAPE --pre-launch
--app /products/testapp.app
--nodeconfig /appium/nodeconfig.json
nodeconfig.json
Issues
• Stability issues
• Actions depends on platform
• Problems with accessing some elements
• iOS specific issues
– Single app test
– Hardware keys support
– One emulator instance
– xpath
Application types
Mobile Browser
Device APIs
Native App
0101010101010101010101010100010011110101001001110010100
00001
<html><body>
<input type="button" value=" + " onclick="plus()"><script language="JavaScript">unction plus()
{rezultat.value=znah_1.value-(-1)*znah_2.value;}
</body></html>
Device APIs
Native Container
<html><body>
<input type="button" value=" + " onclick="plus()"><script language="JavaScript">unction plus()
{rezultat.value=znah_1.value
Web apps
• Similar layouts
• Same locators
• Absolutely the same tests can be executed
• Not require additional efforts
Native apps
• Different layout
• Different locators
• Platform specific UI elements
• Test cases should be specially designed
• Require additional efforts
Test environment
SVN
Jenkins
Web Firefox
Web Chrome
Mobile iOS
Mobile Android
……
Selenium Grid
Chrome, FF
IE
Safari
adb
iPad simulator
iPhone simulator
Nexus 7
Nexus 5
Ap
piu
mreports
Sele
niu
m
Test framework overview
class Drivers
class Bindings
Page ObjectsPage Objects
Page ObjectsPage Objects
TestsTests
TestsTests
Global ConfigurationTest data
loggers/db tools/service tools etc.
Tests
• Test steps should be similar for both platforms
@Test (dataProvider = "Logins")
@Features ("Login")
@Stories ("User should not be able to login with incorrect credentials")
public void verify_Incorrect_Login(Map<String, String> testData){
loginScreen.verifyScreenLoaded();
loginScreen.submitLogin(testData.get("User"),testData.get("Password"));
loginScreen.verifyAndCloseErrorMessage(testData.get("Message"));
loginScreen.verifyScreenLoaded();
}
Page Objects
• Do not hardcode locators in Page objects
• Store it in external object
• Implement platform specific code
• Create bindings for platform specific actions
Page Object
public class LoginScreen extends Bindings {
public LoginScreen(Instance instance) {super(instance);initLocators();
}
private static String LoginScreenUserField;private static String LoginScreenPasswordField;private static String LoginScreenSubmitLoginBtn;private static String LoginScreenErrorMsg;private static String LoginScreenErrorMsgCloseBtn;
private void initLocators() {
LoginScreenUserField = locators.get("LoginScreenUserField");LoginScreenPasswordField = locators.get("LoginScreenPasswordField");LoginScreenSubmitLoginButton = locators.get("LoginScreenSubmitLoginButton");LoginScreenErrorMsg = locators.get("LoginScreenErrorMsg");LoginScreenErrorMsgCloseBtn = locators.get("LoginScreenErrorMsgCloseBtn");
}... ...
Page Object
@Steppublic void submitLogin(String login, String pass) {
typeKeys(LoginScreenUserField, login);typeKeys(LoginScreenPasswordField, pass);tap(LoginScreenSubmitLoginBtn);
}
@Steppublic void verifyAndCloseErrorMessage(String Message) {
verifyElementPresent(LoginScreenErrorMsg);assetEqual(getText(LoginScreenErrorMsg),Message);
if (instance.getPlatform().equals("ios"))tap(LoginScreenErrorMsgCloseBtn);elseclickBackBtn();
}
Locators
<?xml version='1.0' encoding='UTF-8'?><dataset><LOCATORNAME="LoginScreenUserField" ANDROID="id=com.example.myapp:id/txtUser"IOS="xpath=//window[1]/textfield[1]"/>
<LOCATORNAME="LoginScreenPasswordField" ANDROID="id=com.example.myapp:id/txtPassword"IOS="xpath=//window[1]/textfield[2]"/>
<LOCATORNAME="LoginScreenSubmitLoginButton" ANDROID="name=Login " IOS="name=Login"/>
<LOCATORNAME="LoginScreenErrorMsg" ANDROID="id=com.example.myapp:id/errText" IOS="xpath=//*/UIAPopover[contains(@name,'ErrorText')]"/>
<LOCATORNAME="LoginScreenErrorMsgCloseBtn" IOS="name=Ok"/>
...
...
Get locators for Android
Get locators for iOS
Summary
• WebDriver concept
• Cross platform
• Open Source
• Easy integration into Selenium based frameworks
• Supported by community
• One test for two platforms
KEEPCALM
AND
ASKQUESTIONS