Date post: | 13-Jan-2017 |
Category: |
Software |
Upload: | adi-ben-aroya |
View: | 710 times |
Download: | 0 times |
Adi Ben Aroya
Automation Developer
@
On The AgendaPart I - Intro
Part II - Technical
Overview on Gett (GetTaxi)High level Complexity and Challenges
Automation role and responsibilities in GettSelection of tools
Automation Architecture in GettComplexity & Solutions (mobile Automation) Tips & Tricks Q&A
GettPlatform for connecting between supply
and demand for any service.
In other words we are connectingbetween consumers and suppliers
ISRAEL UK RUSSIA NYC
50 Cities
Some Numbers...
Under Development In GettThere are 9 different products...
Android iPhone
Web SitesB2B Solution/Private Site
Driver Box Tablet
Driver App's
For iPhone
For Android&
Kiosk
Our Customers
Drivers
Companies
Business Users
Private Users
Complexity & Challenges
Automation Complexity
Multi platforms under same test
Platform/Product synchronization
Challenge to manage small testable units
Challenge managing test run time
Location Location Location
Order Details On Mobile App
In Order Details View alone there are over50 base permutations based on
configuration and user type.
Different markets, Different Regulations, Different Accountability...
Fix Prices
Internal Meter
External Meter
Taxes
Automation ToolsSelection
As main development language
Object oriented
Fully supports all OS’s
Huge community and open sourcesupport
Android devices and Robotium
SeleniumRuns in many browsers and operating systems
Support many programming languages & testing frameworks.
Open source
Large community
Good documentation
For Headless testing
Based on Selenium
95% Same code
Minimum adaptation & effort
Runs fast
Can Identify problems upon compilation
RobotiumWas the best choice at the time
Written in Java
Client/Server Architecture - Supports real devices & emulators
Supports all API levels
One of the best solutions for iOS automation today
Large active community
Open Source
Pause & suggest...Think about your testing need functional testing, compatibility testing, UI testing, etc.
And pick up the right and best Android testing framework.
Popular
Reliable
Was the company choice and we aligned with it.
Test manager orchestrator
Work with SUTs
Work with many platforms
Optional support of permutations
Not depended (can be replaced at anytime)
Automation role & responsibility
CI/CD - Automation testing for every commit
Headless testing
End to end testing (Full Regression)
Load testing and performance
Post Production
Roles & Responsibility
Continuous deployment automation
Not Fear Code We Are.
Architecture
SUT
Any platform combination
Creates only the system objects needed.
System Under Test.
Java objects which encapsulates the codethat interacts with the SUT
Device and or software being tested.
SUT Structure
<driverBoxIPhone><class>com.gettaxi.automation.gettaxi_auto_infra.mobile.iphone.DriverBoxIphoneImpl</class><timeout>60000</timeout><device>
<class>com.gettaxi.automation.gettaxi_auto_infra.mobile.iphone.so.IphoneSimulatorSO</class> <longitude>34.838557</longitude> <latitude>32.111188</latitude> <iphoneSimulatorPath>/GetTaxi</iphoneSimulatorPath>
<emulatorName>mobile</emulatorName><setLocationOnStart>true</setLocationOnStart><running>true</running>
</device> ...</driverBoxIPhone>
XML configuration file will look like:
The encapsulating Object will be populated atthe @Before stage.
DBX InterFace
Android
AndroidTablet
iPhone
Reflection
Work with interfaces
public interface DriverBoxService {
public enum DriverBoxButton {CASH, CONFIRM, CREDIT_CARD,PASSENGER_ON_BOARD,
PICKED, REJECT, NO, ACCEPT, ...}
public String getPrivatePriceFromDBX() throws Exception; Public void waitForOrder() throws Exception; Public void goBackToMainScreen() throws Exception; Public void enterPrice(Integer price) throws Exception;...
}
ImplementorsDBX Android Implementor
public class DriverBoxAndroidImpl extends SystemObjectImpl implements DriverBoxService,CommunicationListener{
static { androidButtons = new HashMap<String, String>(); androidButtons.put(DriverBoxButton.ONE_MIN.name(), "com.gettaxi.driverbox:id/btn_1_minute"); androidButtons.put(DriverBoxButton.ARRIVED.name(), "com.gettaxi.driverbox:id/btn_arrived");}
R class - contains unique id for each view
public static final int btnYes=0x7f0800b7;public static final int btn_arrived=0x7f080185;public static final int btn_busy=0x7f080181;
ImplementorsDBX iPhone Implementor
public class DriverBoxIphoneImpl extends SystemObjectImpl implements DriverBoxService{
static { iphoneButtons = new HashMap<String, WebLocator>(); iphoneButtons.put(DriverBoxButton.ONE_MIN.name(), orderScreenLocators.ONE_MINUTE); iphoneButtons.put(DriverBoxButton.ARRIVED.name(), orderScreenLocators.ARRIVED);
Object repository
Implements all Bottons and Methods
Set of inner classed divided by logiccontaining all locators.
@Test@TestProperties(name = "${ManualUcID} - Test Sanity 1 - Private Ride Cash + Coupon", paramsInclude = { "orderPrice", "loginForm", "originAddress", "destinationAddress",
"ManualUcID", "tags", "isBrowserNeeded", "driverId"})public void testSanity_1() throws Exception {
orderPrice = 1;
try {//since US not accepting cash this is not relevant if (!GetTaxiSettings.env.name().contains(GetTaxiEnviroment.US.name())){
paymentType = PaymentType.Cash;initTestParameters(UserType.PRIVATE);
report.startLevel("Launch driver box and GetTaxi app", Reporter.EnumReportLevel.CurrentPlace);launchDBXAndClientAndDriverLogin();report.stopLevel();
couponForm.setFirstTimeOnly(false);String couponExternalId = createCoupon();orderTaxiForm.setCouponExternalId(couponExternalId);getTaxiService.addPromotionCode(couponExternalId, true, true);orderTaxiForm.setPrepaidAccountBalance(getTaxiDBService.getTotalAvailableAmountIncludingCouponsForUser(loginFormMobile.getUserId()));
acceptOrderAndPickup(orderTaxiForm, PresentOrFutureRide.NOW, orderPrice);String orderId = getTaxiDBService.getOrderIdByUser(loginFormMobile.getFirstName());validateOrderPricesCalculations(getTaxiDBService, ccsDBService, orderId, loginForm, orderTaxiForm, orderPrice); }
} catch (Exception e) {fail(e);
}pass();
}
Work with interfaces
Test Structure
Call to system objects
Tests are organized in classesbased on same business logic (Private, Business, Future )
Initialize test parametrization
Tips & Tricks
iOS - Tables
If Recognized as UIButton but contained inUITableView handling will be always as table
MobileElement table = (MobileElement) waitForElement("//UIATableView[1]", 200);List<WebElement> rows = table.findElements(By.className("UIAButton"));
switch (tipPrecent) {case _0:
//clickOnImage(GetTaxiButton.ZERO_TIP);rows.get(0).click();break;
case _10://clickOnImage(GetTaxiButton.TEN_TIP);rows.get(1).click();break;
case _12://clickOnImage(GetTaxiButton.TWELVE_TIP);rows.get(2).click();break;
case _15://clickOnImage(GetTaxiButton.FIFTEEN_TIP);rows.get(3).click();break;
default:break;
}
How To Handle Tables
So we inherit all the abstracts of theselenium as part of the client object andenjoy all its capabilities.
Appium as WebDriver
protected AppiumDriver iphoneDriver;
Public WebDriver driver;
AppiumDriver extends RemoteWebDriver
Using the api of the web driver
Public AppiumDrivePageImpl pageImpl
public class AppiumDrivePageImpl extends AbstractPage {
/**/
public AppiumDrivePageImpl(WebDriver driver) throws Exception { super(driver);
if (!isInModule()) { throw new NotInModuleException(ErrorMessages.NOT_IN_MODULE + getClassName(this)); } }
@Override public boolean isInModule() throws Exception { return true;
}
}
Appium as WebDriver Based on the PageObject practice created that inheritfrom our Abstract Page.
if (isAppiumActive && !isIphoneSimActive) { iphoneDriver = getTaxiAppium.connect(); device.setIphoneDriver(iphoneDriver); driver = iphoneDriver; pageImpl = new AppiumDrivePageImpl(driver);
}
On Appium Loading
public void clickOnImage(GetTaxiButton getTaxiButton, long timeout)throws Exception { waitForView(getTaxiButton, timeout); report.report("Click on button: " + getTaxiButton.name()); pageImpl.clickOnButton(iphoneButtons.get(getTaxiButton.name()));}
Usage Example
Usage Example
public void clickOnButton(WebLocator webLocator) throws Exception { Try {
report.report("Click on button: " + webLocator);
printWebLocatorDetails(webLocator);
WebElement element = waitForVisibilityOfElement(webLocator);
clickOnButton(element);
report.report("button: "+ webLocator.getName() + " " + webLocator.getLocator() +" was clicked"); } catch (Exception e) { report.report("Exception caught in Click on button: " + e.getMessage()); throw e; }}
Web implementation of clickOnButton
Set Location Appium
public void setLocation(double latitude, double longitude, double altitude) {
Location location = new Location(latitude,longitude,altitude);
iphoneDriver.setLocation(location);
report.report("set location in Sim : " + latitude +","+ longitude);}
public void setLocation(Location location) {
RemoteLocationContext locationContext.setLocation(location);
}