- It wraps the vendor-provided frameworks in one API -- Selenium WebDriver.
- It is cross-platform: i.e. allowing user to write tests against multiple platforms (iOS, Android, Windows), using the same API.
- It supports multiple scripting languages: Java, Ruby, Python, PHP, JavaScript, C#.
- It specifies a client-server protocol (known as the JSON Wire Protocol).
- It supports testing of native mobile applications, mobile web applications, and hybrid mobile applications.
- It supports testing on a real device or a virtual device (one running on simulators/emulators).
- It supports all major mobile vendors: Android, iOS, FirefoxOS, Windows.
Installation and configuration
Install JDK (Java Development Kit), then:- Add system variable JAVA_HOME (value = JDK installation root directory).
- Append the following to system variable PATH: %JAVA_HOME%\bin
- Add system variable ANDROID_HOME (value = Android SDK installation directory).
- Append the following to system variable PATH: %ANDROID_HOME%\tools; %ANDROID_HOME%\platform-tools
- Open Android SDK Manager.
- Install Android SDK Tools, Platform-tools and at least one Build-tools.
- Install at least one Android API package (with SDK Platform and some system images).
- Note: Unless you have large size of disk space, do not install too many API packages, one could easily take around 10 GB.
- Some packages in Extras may be needed depending on specific tests.
- Install Intel HAXM (Hardware Accelerated Execution Manager). If it fails, install it separately (download installer from Intel site).
Create and configure AVDs (Android Virtual Device) via AVD Manager.
Install Ruby.
After Ruby installed, install the following Ruby gems (gem appium_lib will be installed as a dependency of gem appium_console):
After Node.js installed, install Appium as below:
Create a working directory and place there the example Android application to be tested: e.g. xxxmobile_4.4.2.2.apk.
Run and explore AVD and app:
Open a pry session and execute the following:
I think the reason is that the parsed starting activity by Appium does not match the real one. In this case some extra effort is needed to get the starting activity of the application:
.activities.login.LoginActivity
Modify the desired_caps as following, also add a "newCommandTimeout" key, which specifies the idle time Appium would wait for a new command before killing the current application session:
Identify app elements using UI Automator Viewer:
To automate the app testing, relevant elements of specific screens need to be checked to get their attributes for identification, this can be done by using UI Automator Viewer, a tool similar to UFT's Object Spy. It is located under %ANDROID_HOME%\tools.
Launch an AVD and start the app to be tested, then open UI Automator Viewer, click the "Device Screenshot (uiautomator dump)" button. Elements on the current screen will be presented with detailed attributes.
With the attribute information, elements can be specified in pry so certain actions can be performed, for instance:
Install Ruby.
After Ruby installed, install the following Ruby gems (gem appium_lib will be installed as a dependency of gem appium_console):
gem install appium_consoleInstall Node.js.
gem install selenium-webdriver
After Node.js installed, install Appium as below:
npm install -g appiumNote: I had problem running test using the Appium installed via the Windows installer from appium.io, which is of version 1.4.13 at this time (Feb 15, 2017). The one installed via Node.js, which is of version 1.6.3, runs OK.
Start Appium server
Open a Node.js command window then execute the following:appium --address 127.0.0.1 --port 4723 --log-timestamp --local-timezone
Launch emulator and explore mobile application
Preparation:Create a working directory and place there the example Android application to be tested: e.g. xxxmobile_4.4.2.2.apk.
Run and explore AVD and app:
Open a pry session and execute the following:
require 'appium_lib'Sometimes you may see that the application is launched then shut down, with errors in both Appium and pry consoles.
require 'selenium-webdriver'
desired_caps = {
caps:{
platformName: "Android",
deviceName: "Nexus 6",
avd: "xy_nexus_6",
noReset: true,
app: "<path_to>/XXXmobile_4.4.2.2.apk",
deviceReadyTimeout: 200
}
}
driver = Appium::Driver.new(desired_caps)
driver.start_driver
I think the reason is that the parsed starting activity by Appium does not match the real one. In this case some extra effort is needed to get the starting activity of the application:
- Make sure AVD is still running.
- Open the application (XXX Mobile in this example).
- Open a command window and execute:
adb shellthen
dumpsys window windows | grep -E 'mCurrentFocus|FocusedApp'The response would tell the correct activity, which, in this example, is:
.activities.login.LoginActivity
Modify the desired_caps as following, also add a "newCommandTimeout" key, which specifies the idle time Appium would wait for a new command before killing the current application session:
require 'appium_lib'This would launch the application correctly and load the login screen as expected.
require 'selenium-webdriver'
desired_caps = {
caps:{
platformName: "Android",
deviceName: "Nexus 6",
avd: "xy_nexus_6",
noReset: true,
app: "<path_to>/com.xxx.android.xxxmobile.apk",
appPackage: "com.xxx.android.xxxmobile",
appWaitActivity: ".activities.login.LoginActivity",
deviceReadyTimeout: 200,
newCommandTimeout: 86400
}
}
driver = Appium::Driver.new(desired_caps)
driver.start_driver
Identify app elements using UI Automator Viewer:
To automate the app testing, relevant elements of specific screens need to be checked to get their attributes for identification, this can be done by using UI Automator Viewer, a tool similar to UFT's Object Spy. It is located under %ANDROID_HOME%\tools.
Launch an AVD and start the app to be tested, then open UI Automator Viewer, click the "Device Screenshot (uiautomator dump)" button. Elements on the current screen will be presented with detailed attributes.
With the attribute information, elements can be specified in pry so certain actions can be performed, for instance:
driver.find_element(:id, 'login_username').send_keys "xxxx"
driver.find_element(:id, 'login_password').send_keys "xxxx"
driver.find_element(:id, 'login_button').click
Sample test cases
Attached is a video clip of a sample test case.
Scripting notes
Identifying elements using certain attributes:
See the example below.
For some reason, the following are NOT accepted:
driver.find_element(:text => "CONNECTIONS")
driver.find_element(:xpath => "//*[@resource-id = 'com.xxx.android.xxxmobile:id/psts_tab_title']")
driver.find_element(:xpath => "//*[@id = 'com.xxx.android.xxxmobile:id/psts_tab_title']")
But the following will work:
driver.find_element(:xpath => "//android.widget.TextView[@text = 'CONNECTIONS']")driver.find_element(:xpath => "//*[@text = 'CONNECTIONS']")driver.find_element(:id => "com.xxx.android.xxxmobile:id/psts_tab_title")driver.find_element(:id => "psts_tab_title")
Checking existence of elements:
Sometimes errors are returned when the following is used to check the existence of a certain element:
driver.find_element(...).displayed?
But the following is OK:
driver.find_elements(...).size>0











No comments:
Post a Comment