Mobile Testing Open Source Solu,ons
Top Q Who are we? General Established in 2005, the leading test- automa6on solu6ons company in Israel More than 100 customers in major ver6cal markets, including Networking equipment manufacturers and Java- based vendors Methodology Deploys a tried- and- true project development methodology, proven to build successful and enduring test- automa6on projects Tools Exper6se in all leading test- automa6on plahorms and tools, including commercial to open source Services Complete life- cycle of a test- automa6on solu6on: from ini6al requirement phase, analysis and planning, to implementa6on, maintenance and audit
Customers
We re not going to talk about Tes6ng framework Programming language BDD, TDD, ATDD,KDT etc.
Image Based Approach +
UI Tes,ng UI Integra6on Unit
UI Tes,ng Func6onal black box tes6ng no need of internal implementa6on details of the app, only its expected output when a user performs a specific ac6on or enters a specific input. test the behavior of your applica6on s user interface (UI) when it is running on a device Usually 6me- consuming, tedious, and error- prone when done manually
Fragmenta,on Issues
Fragmenta,on Issues
Fragmenta,on Issues
UI Tes,ng Commercial Framework API PlaIorm Pros Cons SeeTest Java / C# / Perl/Python Android/IOS Works with all devices Works with IOS on PC Perfecto Mobile Recording Selenium API Android/IOS Selenium API Works with IOS on PC A lot of tes6ng devices Ranorex.net Android/ios/ windows mobile DDT supports web and desktop app TestComplete C#/Java Script Android Good KDT Excellent repor6ng Supports DB,Web,Desktop apps etc. QTP VB.net Android Works with other Mobile Automa6on Framworks
UI Tes,ng Open Source Framework API PlaIorm Pros Cons Robo6um Java/C#/ Python etc. Android Works with all Android versions Hybrid Apps Singing Instrumenta6ons App domain only Java/C#/ python etc. Selenium API Android/IOS Selenium API Works with IOS Hybrid Apps Android API 16 and above UI Uiautomator Java/C#/ python etc. Android No need of special permission Controls the whole UI Hybrid Apps Android API 16 and above No WebView control Frank Java/ cucumber IOS Easy to use not enough documenta6on (Xamarin) Cucumber +ruby/java IOS/Android BDD BDD Espresso Java Android Google No mobile web
UI Tes,ng Commercial Framework API PlaIorm Pros Cons Perfecto Mobile Recording Selenium API Android/IOS Selenium API Works with IOS on PC A lot of tes6ng devices SauceLabs Java/Ruby/ PHP/JS/ Python Android/IOS Based on Runs in the cloud Applitools Java/Ruby/ PHP/JS/ Python Android Excellent UI tes6ng tool TestDroid Java/ Cucamber Android/IOS Real devices on cloud Xamarin Test Cloud C# Android/IOS Based on
Instrumenta,on Based Approach A service provided by the different opera6ng systems Designed for unit tes6ng Interfaces with the applica6on UI objects
Instrumenta,on Based Approach The tes6ng applica6on must have permissions on the applica6on under test package In Android we need to use the same signature in the DUT and the test applica6on Provided differently in each OS Enable to test only the applica6on context
Instrumenta,on Based Approach
Robo,um Open source library extending JUnit Black- box test cases for Android apps Supports na6ve, hybrid and mobile web tes6ng Semi- ac6ve open source community with monthly releases
Robo,um example public class NotePadTest extends ActivityInstrumentationTestCase2<NotesList>{ private Solo solo; @Override public void setup() throws Exception { //setup() is run before a test case is started. //This is where the solo object is created. solo = new Solo(getInstrumentation(), getactivity()); { } public void testaddnote() throws Exception { solo.clickonmenuitem("add note"); //Assert that NoteEditor activity is opened solo.assertcurrentactivity("expected NoteEditor activity", "NoteEditor"); solo.entertext(0, "Note 1"); solo.goback(); solo.clickonmenuitem("add note"); solo.entertext(0, "Note 2"); solo.gobacktoactivity("noteslist"); //Takes a screenshot and saves it in "/sdcard/robotium- Screenshots/". solo.takescreenshot(); boolean expected = true; boolean actual = solo.searchtext("note 1") && solo.searchtext("note 2"); assertequals("note 1 and/or Note 2 are not found", expected, actual); }
Robo,um Remote Control Robo6um remote control allows execu6on of Robo6um tests from the deskop No need to deploy tests with the applica6on Java and Python binders Test Code Robo6um Client Json over HTTP Robo6um RC Instrumenta6on
Behavior driven test framework for na6ve Android, na6ve ios and mobile web (Android) installs an HTTP server as an package that listens commands from server New controllers can be implemented in Ruby or Java Tests are executed on server side Each test scenario is described in Cucumber Ruby Client library converts Cucumber commands to either Robo6um or Frank method calls
ios Android
- Gherkin
A Java library, created by Google, containing APIs to create automated customized func6onal UI tests. An execu6on engine to run the tests. allows to write code based UI Tests with no screen resolu6on dependency will work on any Android device from API 16 and above
Viewer A GUI tool to scan and analyze the UI components of an Android applica6on. Inspect the UI of an applica6on in order to find the layout hierarchy and view the proper6es of the individual UI components of an applica6on Aher the installa6on of Android SDK, the tool exists in the /tools/ folder and you can start it by typing: uiautomatorviewer from the command line.
Viewer - Example A screenshot of the Calculator applica6on opens. For example click on 7 bulon and look at the right bolom panel the resource- id value
Wri,ng a Test code example public class CalculatorTest extends TestCase { { public void tes6ngcalculator() throws UiObjectNotFoundExcep6on { getuidevice().presshome(); { UiObject Applica6ons = new UiObject(new UiSelector().descrip6on("Apps")); Applica6ons.clickAndWaitForNewWindow(); UiObject apps = new UiObject(new UiSelector().text("Calc")); apps.click(); UiScrollable ListOfapplica6ons = new UiScrollable(new UiSelector().scrollable(true)); UiObject Calculator = ListOfapplica6ons.getChildByText(new UiSelector().className(android.widget.TextView.class.getName()), "Calculator"); Calculator.clickAndWaitForNewWindow(); UiObject seven = new UiObject(new UiSelector().resourceId("com.android.calculator2:id/digit7")); seven.click(); UiObject plus = new UiObject(new UiSelector().resourceId("com.android.calculator2:id/plus")); plus.click(); UiObject one = new UiObject(new UiSelector().resourceId("com.android.calculator2:id/digit1")); one.click(); UiObject result = new UiObject(new UiSelector().resourceId("com.android.calculator2:id/equal")); result.click(); getuidevice().pressback();
Running a Test Type <sdk_path>/tools/android create <name> - n - t 5 - <path> The <name> is the name of the project that contains your uiautomator test source files, the <path> is the path to the corresponding project directory. In order to find the correct value for the parameter - t, type android list targets. Go to your project directory and type ant build Push the JAR file to your Android device Run the tests by typing adb shell uiautomator runtest <Path/Jar_name> - c <package.test_class> for example: adb shell uiautomator runtest LaunchSe>ngs.jar - c com.uia.tests.launchse>ngs
Server Client Solu,on As can see from the pervious slides the code is compiled and pushed and executed on the DUT To allow more flexible test code (I.e test paramteriza6on) and to enjoy the test framework service Top Q s solu6on is based on client- server architecture over HTTP implanted with JSON- RPC The server contains two compiled jars and it is running on the DUT with the regular execu6on command The server implements an interface that refelects API The client is a lean Java class that uses the same interface over JSON- RPC client UiSelector, UiDevice and UiObject are implemented in both sides
Allows to locate UI elements and perform various opera6ons of them Supports Mac and Windows Supports na6ve, hybrid and web applica6ons Supports ios and Android (and FirfoxOS) Supports real devices and simulators Uses Selenium Webdriver (W3C standard) as a scrip6ng framework
Architecture is an HTTP server that creates and handles WebDriver sessions It starts an server on the device that is listening commands from the main process It receives json requests from client libraries over HTTP On Android executes these commands as either uiautomator or Selendroid commands depending on the API level of the device Tests are driven from a Selenium script on server
Android Architecture
ios Architecture
inspector
API DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setcapability("platformname", "Android"); capabilities.setcapability("app","src/test/resources/com.twitter.android_5.5.0.apk"); capabilities.setcapability("app- package", "com.twitter.android"); capabilities.setcapability("app- activity", ".LoginActivity"); Driver driver = new Driver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); //Find the element in page using a selector locating strategy WebElement element = driver.findelement(mobileby.classname("android.widget.edittext")); //Perform operation on the found element element.sendkeys("jsystemdemo");
Addi,onal Test Tools Fiddler Core Based on fiddler core DLLs Java API Logcat parsing - Wait for specific message - Search for excep6ons GennyMo6on Android Emulator SDK tes6ng Tester appliac6on Client Server architecture with JSON- RPC
Page Object Design Pa\ern Within your applica6on UI there are areas that your tests interact with. A Page Object simply models these as objects within the test code. The Page Object s methods represent the services offered by a par6cular page. The page object encapsulate the UI elements. if the UI changes, the fix need only be applied in one place.
UI Repository In code or in test framework GUI use repository keys instead of real locators Saves 6me between versions In some cases can be used with ios/android versions
UI Repository - GUI
UI Repository - Code public class LoginTests { private String username; private String password; @Test @TestProperties(name="Login successfully with username ${username} and password ${password}", paramsinclude = { "username","password" }) public void loginsuccess() throws Exception{ appiumso.getactions().waitforelement(appiumso.objectrepository.getobject("login.username"),30); appiumso.getactions().sendtext(appiumso.objectrepository.getobject("login.username"), username); appiumso.getactions().sendtext(appiumso.objectrepository.getobject("login.password"), password); appiumso.getactions().click(appiumso.objectrepository.getobject("login.btn")); appiumso.getactions().waitforelement(appiumso.objectrepository.getobject("filemanager.switchbtn"),30); }
Thank you For listening Nir Armon Top Q Nir.armon@top-q.co.il Find me on LinkedIn