轉載:Appium 簡明教學:http://www.testclass.net/appium
https://www.cnblogs.com/fnng/p/4540731.html
Appium 官網:http://appium.io/
Github 地址:https://github.com/appium/appium
主要包括以下幾部分:
下面 下麪這段介紹來自於 appium 的官網。
Appium is an open-source tool you can use to automate mobile native, mobile web, and mobile hybrid applications on iOS and Android platforms. 「Mobile native apps」 are those written using the iOS or Android SDKs. 「Mobile web apps」 are web apps accessed using a mobile browser (Appium supports Safari on iOS and Chrome on Android). 「Mobile hybrid apps」 have a native wrapper around a 「webview」 – a native control that enables interaction with web content. Projects like Phonegap, for example, make it easy to build apps using web technologies that are then bundled into a native wrapper – these are hybrid apps.
Importantly, Appium is 「cross-platform」: it allows you to write tests against multiple platforms (iOS, Android), using the same API. This enables a large or total amount of code reuse between iOS and Android testsuites.
我們可以從上面的介紹裡獲得這樣的一些資訊:
Appium was designed to meet mobile automation needs according to a certain philosophy. The key points of this philosophy can be stated as 4 requirements:
You shouldn’t have to recompile your app or modify it in any way in order to automate it. You shouldn’t be locked into a specific language or framework to write and run your tests. A mobile automation framework shouldn’t reinvent the wheel when it comes to automation APIs. A mobile automation framework should be open source, in spirit and practice as well as in name!
appium 的設計哲學是這樣的:
We meet requirement #2 by wrapping the vendor-provided frameworks in one API, theWebDriver API. WebDriver (aka 「Selenium WebDriver」) specifies a client-server protocol (known as the JSON Wire Protocol). Given this client-server architecture, a client written in any language can be used to send the appropriate HTTP requests to the server. There are already clients written in every popular programming language. This also means that you’re free to use whatever test runner and test framework you want; the client libraries are simply HTTP clients and can be mixed into your code any way you please. In other words, Appium & WebDriver clients are not technically 「test frameworks」 – they are 「automation libraries」. You can manage your test environment any way you like!
We meet requirement #3 in the same way: WebDriver has become the de facto standard for automating web browsers, and is a W3C Working Draft. Why do something totally different for mobile? Instead we have extended the protocol with extra API methods useful for mobile automation.
It should be obvious that requirement #4 is a given – you’re reading this because Appium is open source.
首先,爲了能夠實現哲學裏描述的第2條,也就是不應該讓行動端自動化測試限定在某種語言和某個具體的框架;也就是說任何人都可以使用自己最熟悉最順手的語言以及框架來做行動端自動化測試;appium選擇了client-server的設計模式。只要client能夠發送http請求給server,那麼的話client用什麼語言來實現都是可以的,這就是appium及webdriver如何做到支援多語言的;
其次,爲了能夠實現不要爲了行動端的自動化測試而重新發明輪子,重新寫一套驚天動地的api;也就是說webdriver協定裡的api已經夠好了,拿來改進一下就可以了;這個思想,appium擴充套件了webdriver的協定,沒有自己重新去實現一套。這樣的好處是以前的webdriver api能夠直接被繼承過來,以前的webdriver各種語言的binding都可以拿來就用,省去了爲每種語言開發一個client的工作量;
最後 appium 當然是開源的,這也實現了哲學思想裡的最後一點。
appium 是一個自動化測試開源工具,支援 iOS 平臺和 Android 平臺上的原生應用,web應用和混合應用。
「移動原生應用」是指那些用iOS或者 Android SDK 寫的應用(Application簡稱app)。
「移動web應用」是指使用移動瀏覽器存取的應用(appium支援iOS上的Safari和Android上的 Chrome)。
「混合應用」是指原生程式碼封裝網頁檢視——原生程式碼和 web 內容互動。比如,像 Phonegap,可以幫助開發者使用網頁技術開發應用,然後用原生程式碼封裝,這些就是混合應用。
重要的是,appium是一個跨平臺的工具:它允許測試人員在不同的平臺(iOS,Android)使用同一套API來寫自動化測試指令碼,這樣大大增加了iOS和Android測試套件間程式碼的複用性。
appium類庫封裝了標準Selenium用戶端類庫,爲使用者提供所有常見的JSON格式selenium命令以及額外的移動裝置控制相關的命令,如多點觸控手勢和螢幕朝向。
appium用戶端類庫實現了Mobile JSON Wire Protocol(一個標準協定的官方擴充套件草稿)和W3C WebDriver spec(一個傳輸不可預知的自動化協定,該協定定義了MultiAction 介面)的元素。
appium伺服器端定義了官方協定的擴充套件,爲appium 使用者提供了方便的介面來執行各種裝置動作,例如在測試過程中安裝/解除安裝App。這就是爲什麼我們需要appium特定的用戶端,而不是通用的Selenium 用戶端。當然,appium 用戶端類庫只是增加了一些功能,而實際上這些功能就是簡單的擴充套件了Selenium 用戶端,所以他們仍然可以用來執行通用的Selenium對談。
appium 是跨平臺的,可以用在OSX,Windows以及Linux桌面系統上執行。
appium選擇了Client/Server的設計模式。只要client能夠發送http請求給server,那麼的話client用什麼語言來實現都是可以的,這就是appium及Selenium(WebDriver)如何做到支援多語言的原因;
appium 擴充套件了 WebDriver 的協定,沒有自己重新去實現一套。這樣的好處是以前的 WebDriver API 能夠直接被繼承過來,以前的 Selenium(WebDriver)各種語言的 binding 都可以拿來就用,省去了爲每種語言開發一個 client 的工作量;
語言/框架 | Github地址 |
---|---|
Ruby | https://github.com/appium/ruby_lib |
Python | https://github.com/appium/python-client |
Java | https://github.com/appium/java-client |
JavaScript (Node.js) | https://github.com/admc/wd |
Objective C | https://github.com/appium/selenium-objective-c |
PHP | https://github.com/appium/php-client |
C# (.NET) | https://github.com/appium/appium-dotnet-driver |
RobotFramework | https://github.com/jollychang/robotframework-appiumlibrary |
在安裝和介紹 appium 之前,非常有必要介紹一下appium是如何工作的。
通過上面一張圖簡單展示了 appium 的工具原理。
當我在 MAC 平臺上,通過 Python(python-client )編寫了一個appium自動化指令碼並執行,請求會首先到 appium.dum (MAC下的 appium-Server),appium-Server 通過解析,驅動 iOS 裝置來執行 appium 自動化指令碼。
或者,我在 Windows 平臺上,通過 Java( java-client )編寫了一個 appium 自動化指令碼並執行,請求會首先到 appiumForWindow.zip(Window下的appium-Server),appium-Server通過解析,驅動Android虛擬機器或真機來執行appium指令碼。
所以,你會看到 appium 的強大之處就在於此。
這纔是你最關心的問題,使用 appium 都需要安裝些什麼?其實,從 appium 工作原理你就應該知道需要裝什麼了。
程式語言
appium client
appium Server
測試執行環境
appium 的核心其實是一個暴露了一系列REST API的server。
這個server的功能其實很簡單:監聽一個埠,然後接收由client發送來的command。翻譯這些command,把這些command轉成移動裝置可以理解的形式發送給移動裝置,然後移動裝置執行完這些command後把執行結果返回給appium server,appium server再把執行結果返回給client。
在這裏client其實就是發起command的裝置,一般來說就是我們程式碼執行的機器,執行appium測試程式碼的機器。狹義點理解,可以把client理解成是程式碼,這些程式碼可以是java/ruby/python/js的,只要它實現了webdriver標準協定就可以。
這樣的設計思想帶來了一些好處:
session就是一個對談,在webdriver/appium,你的所有工作永遠都是在session start後纔可以進行的。一般來說,通過POST /session這個URL,然後傳入Desired Capabilities就可以開啓session了。
開啓session後,會返回一個全域性唯一的session id,以後幾乎所有的請求都必須帶上這個session id,因爲這個seesion id代表了你所開啓的瀏覽器或者是移動裝置的模擬器。
進一步思考一下,由於session id是全域性唯一,那麼在同一臺機器上啓動多個session就變成了可能,這也就是selenium gird所依賴的具體理論根據。
Desired Capabilities攜帶了一些設定資訊。從本質上講,這個東東是key-value形式的物件。你可以理解成是java裡的map,python裡的字典,ruby裡的hash以及js裡的json物件。實際上Desired Capabilities在傳輸時就是json物件。
Desired Capabilities最重要的作用是告訴server本次測試的上下文。這次是要進行瀏覽器測試還是行動端測試?如果是行動端測試的話是測試android還是ios,如果測試android的話那麼我們要測試哪個app? server的這些疑問Desired Capabilities都必須給予解答,否則server不買賬,自然就無法完成移動app或者是瀏覽器的啓動。
具體例子如下:
For example, we might set the platformName capability to iOS to tell Appium that we want an iOS session, rather than an Android one. Or we might set the safariAllowPopupscapability to true in order to ensure that, during a Safari automation session, we’re allowed to use JavaScript to open up new windows. See the capabilities doc for the complete list of capabilities available for Appium
這就是每次我們在命令列用 appium 命令開啓的東西。
由於原生的 webdriver api 是爲 web 端設計的,因此在行動端用起來會有點不倫不類。appium 官方提供了一套 appium client,涵蓋多種語言 ruby/java/python,在我看來 ruby client 是實現最好的。在測試的時候,一般要使用這些 client 庫去替換原生的webdriver 庫。這實際上不是替換,算是 client 對原生 webdriver 進行了一些行動端的擴充套件,加入了一些方便的方法,比如 swipe之類,appium client 讓我們可以更方便的寫出可讀性更好的測試用例。
appium server 的 GUI 版本,前者用在 osx 上,後者是 windows 上。視覺化、不需要裝 node,可以看 app 的 UI 結構是這個東東的賣點。
Android SDK(Software Development Kit,軟件開發工具包)提供了 Android API 庫和開發工具構建,測試和偵錯應用程式。簡單來講,Android SDK 可以看做用於開發和執行 Android 應用的一個軟體。
我在官網上沒有找到單獨 Android SDK 的下載鏈接,官方推薦下載包含 Android SDK 的 Android Studio。
Android Studio & Android SDK 下載地址:https://developer.android.google.cn/studio/
一方面是包含 Android SDK 的 Android Studio 的安裝包很大。另一方面它們二者也不是強關聯的。因爲 Appium 也會用到 Android SDK,而 Android Studio 也可以呼叫真機來執行 Android 程式。
所以,Android SDK 下載地址(纔是我們想要的):http://tools.android-studio.org/index.php/sdk
你可以通過別的網站進行下載,身爲IT從業人員,如何利用搜尋工具和科學上網工具是你的必備技能。
將下載的 Android SDK 解壓,將得到如下目錄。
圖 Android SDK目錄
下面 下麪設定 Android 環境變數,方法與Java環境變數類似。我本機的目錄結果爲:
D:\android\android-sdk-windows
下面 下麪設定環境變數:
「我的電腦」 右鍵選單 ---> 屬性 ---> 高階 ---> 環境變數 ---> 系統變數 ---> 新建...
變數名 | 變數值 |
---|---|
ANDROID_HOME | D:\android\Android\sdk |
找到 path 變數名—> 「編輯」 新增:
變數名 | 變數值 |
---|---|
PATH | ;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\tools; |
雙擊 SDK Manage.exe 啓動 SDK 管理器。
你需要科學上網,或者查詢到國內的 Android 映象,安裝一個版本的 Android 虛擬機器。你可以根據自己的喜好選擇安裝 Android 5.0 /5.1 /6.0 /7.0 版本。
這裏推薦一個網站:http://www.androiddevtools.cn/
雙擊 AVD Manage.exe 啓動AVD管理器。
點選 「Create...」 按鈕,建立Android虛擬機器。
不要選擇超過電腦螢幕解析度的 Device,其它選項參考上圖。點選 「OK」 建立完成。在 AVD Manage 工具中選中建立的Android虛擬機器,點選 「Start...」 按鈕啓動。
Android 模擬器已經啓動。
windows 依賴:
安裝 nodejs 通過官方的安裝程式來安裝。
安裝 android 的 sdk 包,(http://developer.android.com/sdk/index.html),執行依賴sdk中的'android'工具。並確保你安裝了Level17或以上的版本api。設定 ANDROID_HOME 系統變數爲你的 Android SDK 路徑,並把 tools platform-tools 兩個目錄加入到系統的 Path 路徑裡。因爲這裏麪包含有一些執行命令
安裝 java 的 JDK,並設定 JAVA_HOME 變數爲你的 JDK 目錄。
appium 官網下載:http://appium.io/downloads.html
下載 Appium-windows-1.18-1.zip 解壓即可
可以建立 Appium.exe 的快捷方式放到桌面上,雙擊啓動,appium server 介面如下。
點選 Start Server,
Appium-Server 已經可以打開了。至於 Appium 的使用我們放到後面的章節進行介紹。
appium client 是對 webdriver 原生 api 的一些擴充套件和封裝。它可以幫助我們更容易的寫出用例,寫出更好懂的用例。
appium client 是配合原生的 webdriver 來使用的,因此二者必須配合使用缺一不可。
內容將涵蓋3個語言,ruby/python/java。
ruby 的 appium client 叫做 appium lib,爲什麼是這樣就不解釋了,總之是歷史原因。
首先 update rubygem 和 bundler (說老實話,真的不需要,但官方文件上這麼寫)
gem update --system ;\
gem update bundler
然後使用gem安裝
gem uninstall -aIx appium_lib ;\(這個也不是必須的)
gem install --no-rdoc --no-ri appium_lib
推薦使用 pip 安裝
pip install Appium-Python-Client
當然了也可以在 Pipy 上下載原始碼安裝
tar -xvf Appium-Python-Client-X.X.tar.gz(windows上用7zip可以解壓)
cd Appium-Python-Client-X.X
python setup.py install
最後,也可以通過 github 安裝(要 git 用戶端)
git clone [email protected]:appium/python-client.git
cd python-client
python setup.py install
執行第一個 Appium 測試
第一步,啓動 Android 模擬器。
第二步,啓動 Appium Server。Appium 在啓動時預設佔用本機的 4723 埠,即:127.0.0.1:4723
第三步,編寫 appnium 測試指令碼。
#coding=utf-8
from appium import webdriver
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '6.0'
desired_caps['deviceName'] = 'Android Emulator'
desired_caps['appPackage'] = 'com.android.calculator2'
desired_caps['appActivity'] = '.Calculator'
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
driver.find_element_by_name("1").click()
driver.find_element_by_name("5").click()
driver.find_element_by_name("9").click()
driver.find_element_by_name("delete").click()
driver.find_element_by_name("9").click()
driver.find_element_by_name("5").click()
driver.find_element_by_name("+").click()
driver.find_element_by_name("6").click()
driver.find_element_by_name("=").click()
driver.quit()
執行上面的指令碼,你將會看到 Android 模擬器如下執行介面:
java-client 安裝與測試:http://www.testclass.net/appium/appium-base-java/
java 的話用 maven 安裝就可以了
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>1.3.0</version>
</dependency>
當然了,也可以自己下載jar包,請自行選擇最新版本。
appium client 擴充套件了原生的 webdriver client 方法
下面 下麪以 java 程式碼爲例,簡單過一下 appium client 提供的適合行動端使用的新方法
resetApp()
getAppString()
sendKeyEvent()
currentActivity()
pullFile()
pushFile()
pullFolder()
hideKeyboard()
runAppInBackground()
performTouchAction()
performMultiTouchAction()
tap()
swipe()
pinch()
zoom()
getNamedTextField()
isAppInstalled()
installApp()
removeApp()
launchApp()
closeApp()
endTestCoverage()
lockScreen()
shake()
complexFind()
scrollTo()
scrollToExact()
openNotifications()
Context Switching: .context(), .getContextHandles(), getContext())
新增的 locator
findElementByAccessibilityId()
findElementsByAccessibilityId()
findElementByIosUIAutomation()
findElementsByIosUIAutomation()
findElementByAndroidUIAutomator()
findElementsByAndroidUIAutomator()
這些方法主要覆蓋了3大類:
appium-desktop 和 appium 這兩個只要有一個安裝好就可以,區別是:
什麼是 Appium-desktop?
專案地址:https://github.com/appium/appium-desktop
專案描述:
Appium Server and Inspector in Desktop GUIs for Mac, Windows, and Linux。
Appium 移動測試中有個很重新的元件 Appium-Server,它主要用來監聽我們的移動裝置(真機或模擬器),然將不同程式語言編寫的 appium 測試指令碼進行解析,然後,驅動移動裝置來執行測試。
但Appium-Server有一兩年沒有更新了。Windows版在 2015 年底止步於的 AppiumForWindows_1_4_16_1.zip
於是,新的工具 Appium-desktop 來了! 它來繼續 Appium-Server的使命,當然, Appium-Server當前仍然是可用的。
下載與安裝
appium-desktop 下載地址:這裏
根據自己的平臺選擇相關的包進行下載。本文以 Windows 爲例,所以選擇 appium-desktop-Setup-1.2.4.exe 檔案進行下載。
安裝過程太簡單了,雙擊 exe 檔案,然後,等待安裝完就好了,中間都不需要你設定任何選項。所以,這裏就不貼圖了。
啓動執行
安裝完成桌面會生成一個紫色的 appium 圖示,雙擊開啓。
預設顯示監控的 host 和 port ,這和 Appium-Server中是一致的。點選 「Start Server V 1.7.1」 按鈕啓動服務。
現在啓動 啓動你的移動裝置(真機或模擬器),編寫 Appium 自動化測試指令碼,可以通過 Appium-desktop 來執行測試了。
至於 Appium-Server , 你可以把它解除安裝了!
啓動 appium 及 android 模擬器
一般情況下,我們都從命令列啓動 appium。
windows下,dos 命令視窗輸入
appium
如果該命令報錯,那麼請重灌 appium
npm install -g appium
如果安裝出錯,請使用淘寶源。
然後請開啓 android 的模擬器,如果沒有請新建一個虛擬裝置。請自行解除裝置鎖定(手動把螢幕解鎖了),以防萬一。
下面 下麪的程式碼以啓動android原生的計算器程式爲例
require 'appium_lib'
caps = { caps: { platformName: 'Android', appActivity: '.Calculator', appPackage: 'com.android.calculator2' },
appium_lib: { sauce_username: nil, sauce_access_key: nil } }
driver = Appium::Driver.new(caps).start_driver
討論:可以看出ruby lib裏面的Appium::Driver類實際上就是原生的webdriver類的子類,當然了,由於ruby語法靈活,也可以使用monkey patch來實現類似功能。
from appium import webdriver
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '4.2'
desired_caps['deviceName'] = 'Android Emulator'
desired_caps['appPackage'] = 'com.android.calculator2'
desired_caps['appActivity'] = '.Calculator'
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
討論:webdriver.Remote實際上就是原生webdriver的子類,另外Remote()建構函式的第一個參數中需要顯示指定appium server監聽的埠
新建 java 專案時候,請注意將 selenium-webdriver 以及 appium client 的 jar 包匯入
import io.appium.java_client.AppiumDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME, "");//這句不是必須的
capabilities.setCapability("deviceName","Android Emulator");
capabilities.setCapability("platformVersion", "4.4");
capabilities.setCapability("platformName","Android");
capabilities.setCapability("appPackage", "com.android.calculator2");
capabilities.setCapability("appActivity", ".Calculator");
AppiumDriver driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
討論:AppiumDrvier 是原生 webdriver 的子類。
在這裏我們可以看到,新建driver的時候必須要指定一個DesiredCapabilities 物件,該物件究竟是何方神聖,下面 下麪會仔細講解。
Desired Capabilities 是在啓動 session 的時候是必須提供的。
Desired Capabilities 本質上是以 key value 字典的方式存放,用戶端將這些鍵值對發給伺服器端,告訴伺服器端我們想要怎麼測試。它告訴 appium Server 這樣一些事情:
Desired Capabilities 設定
Appium 的 Desired Capabilities 基本設定如下:
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "Android Emulator");
capabilities.setCapability("automationName", "Appium");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("platformVersion", "5.1");
capabilities.setCapability("appPackage", "com.android.calculator2");
capabilities.setCapability("appActivity", ".Calculator");
WebDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
參數說明:
更多的參數設定 ,參考 這裏:https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md
定位控制元件首先需要使用一些輔助工具,對於appium實戰android來說,下面 下麪的這些工具(以windows系統爲例)是必須熟練使用的。
獲取 appPackage 和 appActivity:https://blog.csdn.net/mtbaby/article/details/78676477
控制元件的特徵就是控制元件的屬性,可以通過 uiautomatorviewer 去獲取。
在 appium 的定位世界裏,下面 下麪這些方法是可以爲我們使用的。也就是說,我們通過下面 下麪幾個約定好的方式,按照webdriver和appium的DSL(自行搜尋並理解)進行控制元件特徵的描述和定位。
繼承自webdriver的方法,也就是通過這3個特徵可以定位控制元件
由Mobile JSON Wire Protocol 協定中定義的方法,更適合移動裝置上的控制元件定位
在 appium 的 client 對 Mobile JSON Wire Protocol 中定義的方法進行了封裝,使其呼叫起來更加方便
find_element :accessibility_id, 'Animation'
find_elements :accessibility_id, 'Animation'
find_element :uiautomator, 'new UiSelector().clickable(true)'
find_elements :uiautomator, 'new UiSelector().clickable(true)'
當然了,你也可以使用原生的webdriver方法
find_element id: 'resource_id'
另外,ruby lib裡提供了一些非常好用的簡便方法來進行控制元件的定位,好寫,好讀。
更多請看 這裏
el = self.driver.find_element_by_android_uiautomator('new UiSelector().description("Animation")')
self.assertIsNotNone(el)
els = self.driver.find_elements_by_android_uiautomator('new UiSelector().clickable(true)')
self.assertIsInstance(els, list)
el = self.driver.find_element_by_accessibility_id('Animation')
self.assertIsNotNone(el)
els = self.driver.find_elements_by_accessibility_id('Animation')
self.assertIsInstance(els, list)
總的來說就是在 driver 裡增加了
等方法
前面也講過了,新增了這些方法
findElementByAccessibilityId()
findElementsByAccessibilityId()
findElementByIosUIAutomation()
findElementsByIosUIAutomation()
findElementByAndroidUIAutomator()
findElementsByAndroidUIAutomator()
討論:從上面可以看出來,python 和 java client對行動端控制元件定位的封裝是比較初級的。ruby lib中封裝了很多方便和簡潔的方法,因此可以看出,使用ruby lib是優於python和java的選擇。當然,如果忽略效能的話。
appium 通過 uiautomatorviewer.bat 工具來檢視控制元件的屬性。該工具位於 Android SDK 的 /tools/bin/ 目錄下。
通過 uiautomatorviewer.bat 工具可以檢視物件的 id 屬性。
如果目標裝置的 API Level 低於18則 UIAutomatorViewer 不能獲得對應的 Resource ID,只有等於大於18的時候才能 纔能使用。
開啓 uiautomatorviewer.bat 工具:
resource-id 就是我們理解的 id 屬性了。
使用方法:
driver.findElement(By.id("com.android.calculator2:id/formula"))
開啓 uiautomatorviewer.bat 工具:
text 就是我們要查詢的 name 了,爲什麼在命名上毫無關聯啊!
使用方法:
driver.findElement(By.name("9"))
計算器介面上的的 class 屬性是:android.widget.Button。 使用方法:
WebElement button = driver.findElement(By.className("android.widget.Button"));
使用 Class Name 一般獲得的 view 都不止一個,所以應該需要遍歷一遍得到的 views,然後縮小搜尋條件來獲得目標控制元件。
在 WebDriver 上 XPath 定位是功能強大的一種定位方式。我個人慣用於此方法來定位Web頁面上的元素。下面 下麪看看在 Android 上 XPath 定位的用法。
用 class 的屬性來替代做標籤的名字。
使用方法:
driver.findElement(By.xpath("//android.view.ViewGroup/android.widget.Button")) //7
當果如果出現 class 相同的情況下可以用控制元件的屬性值進行區分。
java
driver.findElement(By.xpath("//android.widget.Button[contains(@text,'7')]")).click(); //7
driver.findElement(By.xpath("//android.widget.Button[contains(@content-desc,'times')]")).click(); //*
driver.findElement(By.xpath("//android.widget.Button[contains(@text,'7')]")).click(); //7
driver.findElement(By.xpath("//android.widget.Button[contains(@content-desc,'equals')]")).click(); //=
XPath 在 Appium 上的用法依然很強大,有時需要寫更臭更長的定位語法,因爲APP上元素的class命令本來就長,再加上多層級,結果可想而知。
這個方法屬於 Appium 擴充套件的定位方法。
其實,我們的核心是要找到元素的 contentDescription 屬性。它就是元素的 content-desc 。
使用方法:
java driver.findElementByAccessibilityId("plus").click();
這個方法也屬於 Appium(Android)擴充套件的定位方法。同樣使用 UIAutomatorViewer.bat 工具直接檢視。
也就是說一個元素的任意屬性都可以通過 android uiautomator 方法來進行定位,但要保證這種定位方式的唯一性。
使用方法:
driver.findElementByAndroidUIAutomator("new UiSelector().text(\"clr\")").click();
driver.findElementByAndroidUIAutomator("new UiSelector().text(\"8\")").click();
driver.findElementByAndroidUIAutomator("new UiSelector().description(\"plus\")").click();
driver.findElementByAndroidUIAutomator("new UiSelector().text(\"5\")").click();
driver.findElementByAndroidUIAutomator("new UiSelector().description(\"equals\")").click();
需要注意的是 description() 方法用的是 content-desc 屬性。
羅列的方法主要針對應用的操作,如應用的安裝、解除安裝、關閉、啓動等。
方法:installApp()
安裝應用到裝置中去。需要apk包的路徑。
driver.installApp("path/to/my.apk");
driver.installApp("D:\\android\\apk\\ContactManager.apk");
方法:removeApp()
從裝置中刪除一個應用。 java driver.removeApp("com.example.android.apis");
方法:closeApp()
關閉開啓的應用,預設關閉當前開啓的應用,所以不需要入參。這個方法並非真正的關閉應用,相當於按home鍵將應用置於後臺,可以通過launchApp()再次啓動。
方法:launchApp()
啓動應用。你一定很迷惑,不是在初始化的設定資訊已經指定了應用,指令碼執行的時候就需要啓動應用,爲什麼還要有這個方法去啓動應用呢?重新啓動應用也是一個測試點,該方法需要配合closeApp()使用的。 java driver.closeApp(); driver.launchApp();
方法:isAppInstalled()
檢查應用是否已經安裝。需要傳參應用包的名字。返回結果爲Ture或False。 java driver.isAppInstalled('com.example.android.apis');
方法:runAppInBackground()
將當前活躍的應用程式發送到後臺。這個方法需要入參,需要指定應用置於後臺的時長。
driver.runAppInBackground(2);
方法:resetApp()
重置當前被測程式到出始化狀態。該方法不需要入參。 java driver.resetApp();
其實上下文的操作主要針對於混合應用。
啥是混合應用,簡單來說就是APP用裏面嵌入網頁。Android上的瀏覽器就屬於混合應用。
方法:getContext()
獲取當前所有的可用的上下文。該方法不需要入參。 ```java String ct = driver.getContext(); System.out.println(ct);
-----------計算器應用的列印結果----------------------- NATIVE_APP ```
方法:getContextHandles()
獲取當前所有可用的上下文。該方法不需要入參。
方法:context()
切換到特定的上下文中。需要指定上下文的名稱。 java driver.context('NATIVE_APP') driver.context('WEBVIEW_1')
模擬鍵盤輸入也是非常重要的操作。這一小節來介紹那些關於鍵盤的操作。
方法:sendKeys()
用法:
driver.findElements(By.name("Name")).sendKeys("jack");
除此之外,appium擴充套件提供了pressKeyCode()方法。該方法 Android 特有。
方法:pressKeyCode()
發送一個鍵碼的操作。需要一個入參。
driver.pressKeyCode(29); // 字母「a」
如果想點選 Android 的 HOME 鍵應該怎麼實現的呢?如下 java driver.pressKeyCode(AndroidKeyCode.HOME);
下面 下麪提供Android keycode參考表:
電話鍵
KEYCODE_CALL 撥號鍵 5
KEYCODE_ENDCALL 掛機鍵 6
KEYCODE_HOME 按鍵Home 3
KEYCODE_MENU 選單鍵 82
KEYCODE_BACK 返回鍵 4
KEYCODE_SEARCH 搜尋鍵 84
KEYCODE_CAMERA 拍照鍵 27
KEYCODE_FOCUS 拍照對焦鍵 80
KEYCODE_POWER 電源鍵 26
KEYCODE_NOTIFICATION 通知鍵 83
KEYCODE_MUTE 話筒靜音鍵 91
KEYCODE_VOLUME_MUTE 揚聲器靜音鍵 164
KEYCODE_VOLUME_UP 音量增加鍵 24
KEYCODE_VOLUME_DOWN 音量減小鍵 25
控制鍵
KEYCODE_ENTER 回車鍵 66
KEYCODE_ESCAPE ESC鍵 111
KEYCODE_DPAD_CENTER 導航鍵 確定鍵 23
KEYCODE_DPAD_UP 導航鍵 向上 19
KEYCODE_DPAD_DOWN 導航鍵 向下 20
KEYCODE_DPAD_LEFT 導航鍵 向左 21
KEYCODE_DPAD_RIGHT 導航鍵 向右 22
KEYCODE_MOVE_HOME 遊標移動到開始鍵 122
KEYCODE_MOVE_END 遊標移動到末尾鍵 123
KEYCODE_PAGE_UP 向上翻頁鍵 92
KEYCODE_PAGE_DOWN 向下翻頁鍵 93
KEYCODE_DEL 退格鍵 67
KEYCODE_FORWARD_DEL 刪除鍵 112
KEYCODE_INSERT 插入鍵 124
KEYCODE_TAB Tab鍵 61
KEYCODE_NUM_LOCK 小鍵盤鎖 143
KEYCODE_CAPS_LOCK 大寫鎖定鍵 115
KEYCODE_BREAK Break/Pause鍵 121
KEYCODE_SCROLL_LOCK 卷動鎖定鍵 116
KEYCODE_ZOOM_IN 放大鍵 168
KEYCODE_ZOOM_OUT 縮小鍵 169
組合鍵
KEYCODE_ALT_LEFT Alt+Left
KEYCODE_ALT_RIGHT Alt+Right
KEYCODE_CTRL_LEFT Control+Left
KEYCODE_CTRL_RIGHT Control+Right
KEYCODE_SHIFT_LEFT Shift+Left
KEYCODE_SHIFT_RIGHT Shift+Right
基本
KEYCODE_0 按鍵'0' 7
KEYCODE_1 按鍵'1' 8
KEYCODE_2 按鍵'2' 9
KEYCODE_3 按鍵'3' 10
KEYCODE_4 按鍵'4' 11
KEYCODE_5 按鍵'5' 12
KEYCODE_6 按鍵'6' 13
KEYCODE_7 按鍵'7' 14
KEYCODE_8 按鍵'8' 15
KEYCODE_9 按鍵'9' 16
KEYCODE_A 按鍵'A' 29
KEYCODE_B 按鍵'B' 30
KEYCODE_C 按鍵'C' 31
KEYCODE_D 按鍵'D' 32
KEYCODE_E 按鍵'E' 33
KEYCODE_F 按鍵'F' 34
KEYCODE_G 按鍵'G' 35
KEYCODE_H 按鍵'H' 36
KEYCODE_I 按鍵'I' 37
KEYCODE_J 按鍵'J' 38
KEYCODE_K 按鍵'K' 39
KEYCODE_L 按鍵'L' 40
KEYCODE_M 按鍵'M' 41
KEYCODE_N 按鍵'N' 42
KEYCODE_O 按鍵'O' 43
KEYCODE_P 按鍵'P' 44
KEYCODE_Q 按鍵'Q' 45
KEYCODE_R 按鍵'R' 46
KEYCODE_S 按鍵'S' 47
KEYCODE_T 按鍵'T' 48
KEYCODE_U 按鍵'U' 49
KEYCODE_V 按鍵'V' 50
KEYCODE_W 按鍵'W' 51
KEYCODE_X 按鍵'X' 52
KEYCODE_Y 按鍵'Y' 53
KEYCODE_Z 按鍵'Z' 54
Appium 的輔助類,主要針對手勢操作,比如滑動、長按、拖動等。
方法:press()
開始按壓一個元素或座標點(x,y)。通過手指按壓手機螢幕的某個位置。
press(WebElement el, int x, int y)
press 也可以接收螢幕的座標(x,y)。
例:
TouchAction(driver).press(x=0,y=308).release().perform()
除了press()方法之外,本例中還用到了別外兩個新方法。
release() 結束的行動取消螢幕上的指針。
Perform() 執行的操作發送到伺服器的命令操作。
方法:longPress()
開始按壓一個元素或座標點(x,y)。 相比press()方法,longPress()多了一個入參,既然長按,得有按的時間吧。duration以毫秒爲單位。1000表示按一秒鐘。其用法與press()方法相同。
longPress(WebElement el, int x, int y, Duration duration)
例: java TouchAction action = new TouchAction(driver); action.longPress(names.get(1),1000).perform().release(); action.longPress(1 ,302,1000).perform().release();
方法:tap()
對一個元素或控制元件執行點選操作。用法參考press()。
tap(WebElement el, int x, int y)
例: java TouchAction action = new TouchAction(driver); action.tap(names.get(1)).perform().release(); action.tap(1 ,302).perform().release();
方法:moveTo()
將指針(遊標)從過去指向指定的元素或點。
movTo(WebElement el, int x, int y)
其用法參考press()方法。
例: Java TouchAction action = new TouchAction(driver); action.moveTo(names.get(1)).perform().release(); action.moveTo(1 ,302).perform().release();
方法:wait()
暫停指令碼的執行,單位爲毫秒。 Java action.wait(1000);
其它操作針對移動裝置上特有的一些操作。
方法: * lockDevice()
點選電源鍵熄滅螢幕。
在iOS裝置可以設定熄屏一段時間。Android上面不帶參數,所以熄屏之後就不會再點亮螢幕了。 java driver.lockDevice(1000); // iOS driver.lockDriice(); //Android
方法:currentActivity()
得到當前應用的activity。只適用於Android。 例(通訊錄): Java String ca = driver.currentActivity(); System.out.print(ca); -------------輸出結果爲------------- .activities.PeopleActivity
方法:hideKeyboard()
收起鍵盤,這個方法很有用,當我們對一個輸入框輸入完成後,需要將鍵盤收起,再切換到一下輸入框進行輸入。 Java driver.hideKeyboard(); //收起鍵盤
方法:swipe()
模擬使用者滑動。將控制元件或元素從一個位置(x,y)拖動到另一個位置(x,y)。
swipe(int startx, int starty, int endx, int endy, int duration) * start_x:開始滑動的x座標。 * start_y:開始滑動的y座標。 * end_x:結束滑動的x座標。 * end_y:結束滑動的y座標。 * duration:持續時間。
例: Java driver.swipe(75, 500, 75, 0, 800);
方法:pullFile()
從裝置中拉出檔案。
例: Java driver.pullFile('Library/AddressBook/AddressBook.sqlitedb')
方法:pushFile()
推播檔案到裝置中去。
pushFile(String remotePath, byte[] base64Data)
例: Java String content = "some data for the file"; byte[] data = Base64.encodeBase64(content.getBytes()); driver.pushFile("sdcard/test.txt", data);