Appium 簡明教學

2020-08-08 20:17:44

 

轉載:Appium 簡明教學:http://www.testclass.net/appium

            https://www.cnblogs.com/fnng/p/4540731.html

 

Appium 官網:http://appium.io/

Github 地址:https://github.com/appium/appium

 

主要包括以下幾部分:

 

 

 

1. 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.

我們可以從上面的介紹裡獲得這樣的一些資訊:

  • 1,appium 是開源的行動端自動化測試框架;
  • 2,appium 可以測試原生的、混合的、以及行動端的 web 專案;
  • 3,appium 可以測試 ios,android 應用(當然了,還有 firefox os);
  • 4,appium 是跨平臺的,可以用在 osx,windows 以及 linux 桌面系統上;

 

appium 的哲學

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 的設計哲學是這樣的:

  • 1,不需要爲了自動化而且重新編譯或修改測試app;
  • 2,不應該讓行動端自動化測試限定在某種語言和某個具體的框架;也就是說任何人都可以使用自己最熟悉最順手的語言以及框架來做行動端自動化測試;
  • 3,不要爲了行動端的自動化測試而重新發明輪子,重新寫一套驚天動地的 api;也就是說 webdriver 協定裡的 api 已經夠好了,拿來改進一下就可以了;
  • 4,行動端自動化測試應該是開源的;

 

appium 的技術架構

  • iOS: Apple’s UIAutomation
  • Android 4.2+: Google’s UiAutomator
  • Android 2.3+: Google’s Instrumentation. (Instrumentation support is provided by bundling a separate project, Selendroid)

 

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 當然是開源的,這也實現了哲學思想裡的最後一點。

 

1、特點


appium 是一個自動化測試開源工具,支援 iOS 平臺和 Android 平臺上的原生應用,web應用和混合應用。

  • 「移動原生應用」是指那些用iOS或者 Android SDK 寫的應用(Application簡稱app)。

  • 「移動web應用」是指使用移動瀏覽器存取的應用(appium支援iOS上的Safari和Android上的 Chrome)。

  • 「混合應用」是指原生程式碼封裝網頁檢視——原生程式碼和 web 內容互動。比如,像 Phonegap,可以幫助開發者使用網頁技術開發應用,然後用原生程式碼封裝,這些就是混合應用。

重要的是,appium是一個跨平臺的工具:它允許測試人員在不同的平臺(iOS,Android)使用同一套API來寫自動化測試指令碼,這樣大大增加了iOS和Android測試套件間程式碼的複用性。

 

2、appium 與 Selenium


appium類庫封裝了標準Selenium用戶端類庫,爲使用者提供所有常見的JSON格式selenium命令以及額外的移動裝置控制相關的命令,如多點觸控手勢和螢幕朝向。

appium用戶端類庫實現了Mobile JSON Wire Protocol(一個標準協定的官方擴充套件草稿)和W3C WebDriver spec(一個傳輸不可預知的自動化協定,該協定定義了MultiAction 介面)的元素。

appium伺服器端定義了官方協定的擴充套件,爲appium 使用者提供了方便的介面來執行各種裝置動作,例如在測試過程中安裝/解除安裝App。這就是爲什麼我們需要appium特定的用戶端,而不是通用的Selenium 用戶端。當然,appium 用戶端類庫只是增加了一些功能,而實際上這些功能就是簡單的擴充套件了Selenium 用戶端,所以他們仍然可以用來執行通用的Selenium對談。

 

3、支援多平臺、多語言


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

 

4、appium 工作原理


在安裝和介紹 appium 之前,非常有必要介紹一下appium是如何工作的。

通過上面一張圖簡單展示了 appium 的工具原理。

  • 首先,appium 支援多語言,因爲它針對流的幾種語言分別開發的相應的 appium 庫。好處就是我們可以選擇自己熟悉的語言編寫 appium 指令碼。
  • 其次,appium 支援多平臺,包括 MAC 和 Windows。它針對這兩大平臺開發了 appium-Server。
  • 最後,appium 又同時支援 Android 和 iOS 兩個操作系統。這就使得 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 的強大之處就在於此。

 

5、你都需要安裝什麼?


這纔是你最關心的問題,使用 appium 都需要安裝些什麼?其實,從 appium 工作原理你就應該知道需要裝什麼了。

程式語言

appium client

  • 參考 3、支援多平臺、多語言 的列表,根據你選擇的語言來選擇對應的 appium-client。

appium Server

  • 參考 4、appium工作原理 的介紹,根據你的系統平臺選擇 對應的 appium-server。

測試執行環境

  • 你需要一個 Android 模擬器,或 一個 Android 手機,或 一臺 iPhone 手機。

 

 

appium 的基本概念

Client / Server Architecture

appium 的核心其實是一個暴露了一系列REST API的server。

這個server的功能其實很簡單:監聽一個埠,然後接收由client發送來的command。翻譯這些command,把這些command轉成移動裝置可以理解的形式發送給移動裝置,然後移動裝置執行完這些command後把執行結果返回給appium server,appium server再把執行結果返回給client。

在這裏client其實就是發起command的裝置,一般來說就是我們程式碼執行的機器,執行appium測試程式碼的機器。狹義點理解,可以把client理解成是程式碼,這些程式碼可以是java/ruby/python/js的,只要它實現了webdriver標準協定就可以。

這樣的設計思想帶來了一些好處:

  • 1,可以帶來多語言的支援;
  • 2,可以把server放在任意機器上,哪怕是雲伺服器都可以;(是的,appium和webdriver天生適合雲測試)

 

Session

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

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 Server

這就是每次我們在命令列用 appium 命令開啓的東西。

 

Appium Clients

由於原生的 webdriver api 是爲 web 端設計的,因此在行動端用起來會有點不倫不類。appium 官方提供了一套 appium client,涵蓋多種語言 ruby/java/python,在我看來 ruby client 是實現最好的。在測試的時候,一般要使用這些 client 庫去替換原生的webdriver 庫。這實際上不是替換,算是 client 對原生 webdriver 進行了一些行動端的擴充套件,加入了一些方便的方法,比如 swipe之類,appium client 讓我們可以更方便的寫出可讀性更好的測試用例。

 

Appium.app、Appium.exe

appium server 的 GUI 版本,前者用在 osx 上,後者是 windows 上。視覺化、不需要裝 node,可以看 app 的 UI 結構是這個東東的賣點。

 

 

 

2. 安裝 Android SDK


Android SDK(Software Development Kit,軟件開發工具包)提供了 Android API 庫和開發工具構建,測試和偵錯應用程式。簡單來講,Android SDK 可以看做用於開發和執行 Android 應用的一個軟體。

 

1、下載 Android SDK


我在官網上沒有找到單獨 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目錄

 

2、設定 Android 環境變數


下面 下麪設定 Android 環境變數,方法與Java環境變數類似。我本機的目錄結果爲:

D:\android\android-sdk-windows

下面 下麪設定環境變數:

「我的電腦」 右鍵選單 ---> 屬性 ---> 高階 ---> 環境變數 ---> 系統變數 ---> 新建...

變數名 變數值
ANDROID_HOME D:\android\Android\sdk

找到 path 變數名—> 「編輯」 新增:

變數名 變數值
PATH ;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\tools;

 

3、安裝 Android 版本


雙擊 SDK Manage.exe 啓動 SDK 管理器。

你需要科學上網,或者查詢到國內的 Android 映象,安裝一個版本的 Android 虛擬機器。你可以根據自己的喜好選擇安裝 Android 5.0 /5.1 /6.0 /7.0 版本。

這裏推薦一個網站:http://www.androiddevtools.cn/

 

4、建立 Android 虛擬機器

雙擊 AVD Manage.exe 啓動AVD管理器。

點選 「Create...」 按鈕,建立Android虛擬機器。

不要選擇超過電腦螢幕解析度的 Device,其它選項參考上圖。點選 「OK」 建立完成。在 AVD Manage 工具中選中建立的Android虛擬機器,點選 「Start...」 按鈕啓動。

Android 模擬器已經啓動。

 

 

 

3. 安裝 appium Server

 

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 的使用我們放到後面的章節進行介紹。

 

 

 

4. appium client 的安裝

 

appium client 是對 webdriver 原生 api 的一些擴充套件和封裝。它可以幫助我們更容易的寫出用例,寫出更好懂的用例。

appium client 是配合原生的 webdriver 來使用的,因此二者必須配合使用缺一不可。

內容將涵蓋3個語言,ruby/python/java。

 

安裝 appium client

 

ruby 篇(一定要線上安裝)

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

 

python篇(儘量線上安裝)

推薦使用 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 篇(線上安裝)

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包,請自行選擇最新版本。

 

 

 

5. appium client 方法一覽

 

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大類:

  • driver 擴充套件:比如增加了resetApp等操作 app 的方法
  • action 擴充套件:增加一些行動端的特有的 action(怎麼描述呢,相當於是行動端 特有的操作),比如 swipe,shake (嗯,有了這個方法就可以讓程式碼幫你搖一搖了) 等;
  • locator 擴充套件:增加了一些行動端專屬的定位策略

 

 

 

6. appium-desktop 和 appium

 

appium-desktopappium 這兩個只要有一個安裝好就可以,區別是:

  • appium-desktop 是帶 GUI 介面
  • appium 是命令列,不帶 GUI 介面

 

appium-desktop

 

什麼是 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

 

啓動 appium 及 android 模擬器

一般情況下,我們都從命令列啓動 appium。

windows下,dos 命令視窗輸入

appium

如果該命令報錯,那麼請重灌 appium

npm install -g appium

如果安裝出錯,請使用淘寶源。

淘寶源地址http://npm.taobao.org/

然後請開啓 android 的模擬器,如果沒有請新建一個虛擬裝置。請自行解除裝置鎖定(手動把螢幕解鎖了),以防萬一。

下面 下麪的程式碼以啓動android原生的計算器程式爲例

 

ruby篇

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來實現類似功能。

 

python篇

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篇

新建 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 物件,該物件究竟是何方神聖,下面 下麪會仔細講解。

 

 

 

7. Desired Capabilities

 

Desired Capabilities 是在啓動 session 的時候是必須提供的。

 

Desired Capabilities 本質上是以 key value 字典的方式存放,用戶端將這些鍵值對發給伺服器端,告訴伺服器端我們想要怎麼測試。它告訴 appium Server 這樣一些事情:

  • 本次測試是 啓動瀏覽器 還是 啓動移動裝置。
  • 是啓動 Andorid 還是啓動iOS。
  • 啓動Android時,app的package是什麼。
  • 啓動Android時,app的activity是什麼。
  • ...

 

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);

參數說明:

  • deviceName:啓動哪種裝置,是真機還是模擬器?iPhone Simulator,iPad Simulator,iPhone Retina 4-inch,Android Emulator,Galaxy S4...
  • automationName:使用哪種自動化引擎。appium(預設)還是Selendroid。
  • platformName:使用哪種移動平臺。iOS, Android, orFirefoxOS。
  • platformVersion:指定平臺的系統版本。例如指的Android平臺,版本爲5.1。
  • appActivity:待測試的app的Activity名字。比如MainActivity、.Settings。注意,原生app的話要在activity前加個"."。
  • appPackage:待測試的app的Java package。比如com.example.android.myApp, com.android.settings。

更多的參數設定 ,參考 這裏https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md

 

 

 

8. 定位控制元件

 

輔助工具

定位控制元件首先需要使用一些輔助工具,對於appium實戰android來說,下面 下麪的這些工具(以windows系統爲例)是必須熟練使用的。

  • monitor.bat(hierarchyviewer.bat 已經不贊成繼續使用了):該檔案位於 your_andriod_sdk_path\tools 下面 下麪(我本機路徑是:D:\SoftWare\AndroidSDK\tools)。該工具可以幫我們找到 android 控制元件的 content-description,爲以後的 find_element_by_accessibility_id 定位方法做參數使用。關於什麼是 content-description,可以參考官方文件
  • uiautomatorviewer.bat:該檔案位於 your_andriod_sdk_path\tools下面 下麪( 我本機路徑:D:\SoftWare\AndroidSDK\tools\bin )。該工具主要用來檢視控制元件的屬性,比如 resource id,class name 等。該工具也可檢視被測 app 的 appPackage( Desired Capabilities 中使用 )。

 

如何獲取 android app 的 Activity

獲取 appPackage 和 appActivity:https://blog.csdn.net/mtbaby/article/details/78676477

  • linux/mac:adb dumpsys activity activities | grep mFocusedActivity
  • for windows: adb dumpsys activity activities | findstr mFocusedActivity

 

 

控制元件定位基礎

控制元件的特徵就是控制元件的屬性,可以通過 uiautomatorviewer 去獲取。

在 appium 的定位世界裏,下面 下麪這些方法是可以爲我們使用的。也就是說,我們通過下面 下麪幾個約定好的方式,按照webdriver和appium的DSL(自行搜尋並理解)進行控制元件特徵的描述和定位。

繼承自webdriver的方法,也就是通過這3個特徵可以定位控制元件

  • find by "class" (i.e., ui component type,andorid上可以是android.widget.TextView)
  • find by "xpath" (i.e., an abstract representation of a path to an element, with certain constraints,由於appium的xpath庫不完備的原因,這個不太推薦)
  • find by "id"(android上是控制元件的resource id)

Mobile JSON Wire Protocol 協定中定義的方法,更適合移動裝置上的控制元件定位

  • -ios uiautomation: a string corresponding to a recursive element search using the UIAutomation library (iOS-only)
  • -android uiautomator: a string corresponding to a recursive element search using the UiAutomator Api (Android-only)
  • accessibility id: a string corresponding to a recursive element search using the Id/Name that the native Accessibility options utilize.

在 appium 的 client 對 Mobile JSON Wire Protocol 中定義的方法進行了封裝,使其呼叫起來更加方便

 

ruby篇

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裡提供了一些非常好用的簡便方法來進行控制元件的定位,好寫,好讀。

  • text(value_or_index) :Find the first TextView that contains value or by index. If int then the TextView at that index is returned.
  • button(value_or_index):Find the first button that contains value or by index. If int then the button at that index is returned

更多請看 這裏

 

python篇

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 裡增加了

  • find_element_by_accessibility_id
  • find_elements_by_accessibility_id
  • find_element_by_android_uiautomator
  • find_elements_by_android_uiautomator

等方法

 

java篇

前面也講過了,新增了這些方法

findElementByAccessibilityId()
findElementsByAccessibilityId()
findElementByIosUIAutomation()
findElementsByIosUIAutomation()
findElementByAndroidUIAutomator()
findElementsByAndroidUIAutomator()

討論:從上面可以看出來,python 和 java client對行動端控制元件定位的封裝是比較初級的。ruby lib中封裝了很多方便和簡潔的方法,因此可以看出,使用ruby lib是優於python和java的選擇。當然,如果忽略效能的話。

 

 

控制元件定位

appium 通過 uiautomatorviewer.bat 工具來檢視控制元件的屬性。該工具位於 Android SDK 的 /tools/bin/ 目錄下。

 

id 定位


通過 uiautomatorviewer.bat 工具可以檢視物件的 id 屬性。

如果目標裝置的 API Level 低於18則 UIAutomatorViewer 不能獲得對應的 Resource ID,只有等於大於18的時候才能 纔能使用。

開啓 uiautomatorviewer.bat 工具:

resource-id 就是我們理解的 id 屬性了。

 

使用方法:

driver.findElement(By.id("com.android.calculator2:id/formula"))

 

name 定位


開啓 uiautomatorviewer.bat 工具:

text 就是我們要查詢的 name 了,爲什麼在命名上毫無關聯啊!

 

使用方法:

driver.findElement(By.name("9"))

 

class name 定位


計算器介面上的的 class 屬性是:android.widget.Button。 使用方法:

WebElement button = driver.findElement(By.className("android.widget.Button"));

使用 Class Name 一般獲得的 view 都不止一個,所以應該需要遍歷一遍得到的 views,然後縮小搜尋條件來獲得目標控制元件。

 

XPath 定位


在 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命令本來就長,再加上多層級,結果可想而知。

 

Accessibility ID 定位


這個方法屬於 Appium 擴充套件的定位方法。

其實,我們的核心是要找到元素的 contentDescription 屬性。它就是元素的 content-desc 。

使用方法:

java driver.findElementByAccessibilityId("plus").click();

 

android uiautomator 定位


這個方法也屬於 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 屬性。

 

 

 

9. appium API 之應用操作

 

羅列的方法主要針對應用的操作,如應用的安裝、解除安裝、關閉、啓動等。

 

1、安裝應用

方法:installApp()

安裝應用到裝置中去。需要apk包的路徑。

driver.installApp("path/to/my.apk");
driver.installApp("D:\\android\\apk\\ContactManager.apk");

 

2、解除安裝應用

方法:removeApp()

從裝置中刪除一個應用。 java driver.removeApp("com.example.android.apis");

 

3、關閉應用

方法:closeApp()

關閉開啓的應用,預設關閉當前開啓的應用,所以不需要入參。這個方法並非真正的關閉應用,相當於按home鍵將應用置於後臺,可以通過launchApp()再次啓動。

 

4、啓動應用

方法:launchApp()

啓動應用。你一定很迷惑,不是在初始化的設定資訊已經指定了應用,指令碼執行的時候就需要啓動應用,爲什麼還要有這個方法去啓動應用呢?重新啓動應用也是一個測試點,該方法需要配合closeApp()使用的。 java driver.closeApp(); driver.launchApp();

 

5、檢查應用是否安裝

方法:isAppInstalled()

檢查應用是否已經安裝。需要傳參應用包的名字。返回結果爲Ture或False。 java driver.isAppInstalled('com.example.android.apis');

 

6、將應用置於後臺

方法:runAppInBackground()

將當前活躍的應用程式發送到後臺。這個方法需要入參,需要指定應用置於後臺的時長。

driver.runAppInBackground(2);

 

7、應用重置

方法:resetApp()

重置當前被測程式到出始化狀態。該方法不需要入參。 java driver.resetApp();

 

 

 

10. appium API 之上下文操作

 

其實上下文的操作主要針對於混合應用。

啥是混合應用,簡單來說就是APP用裏面嵌入網頁。Android上的瀏覽器就屬於混合應用。

 

1、獲取當前上下文

方法:getContext()

獲取當前所有的可用的上下文。該方法不需要入參。 ```java String ct = driver.getContext(); System.out.println(ct);

-----------計算器應用的列印結果----------------------- NATIVE_APP ```

 

2、當前所有上下文控制代碼

方法:getContextHandles()

獲取當前所有可用的上下文。該方法不需要入參。

 

3、切換上下文

方法:context()

切換到特定的上下文中。需要指定上下文的名稱。 java driver.context('NATIVE_APP') driver.context('WEBVIEW_1')

 

 

 

11. appium API 之鍵盤操作

 

模擬鍵盤輸入也是非常重要的操作。這一小節來介紹那些關於鍵盤的操作。

 

1、sendKeys() 方法

方法:sendKeys()

用法:

driver.findElements(By.name("Name")).sendKeys("jack");

 

2、pressKeyCode() 方法

除此之外,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

 

 

 

12. appium API 之 TouchAction 操作

 

Appium 的輔助類,主要針對手勢操作,比如滑動、長按、拖動等。

 

1、按壓控制元件

方法: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() 執行的操作發送到伺服器的命令操作。

 

2、長按控制元件

方法: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();

 

3、點選控制元件

方法: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();

 

4、移動

方法: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();

 

5、暫停

方法:wait()

暫停指令碼的執行,單位爲毫秒。 Java action.wait(1000);

 

 

 

13. appium API 之其他操作

 

其它操作針對移動裝置上特有的一些操作。

 

1、熄屏

方法: * lockDevice()

點選電源鍵熄滅螢幕。

在iOS裝置可以設定熄屏一段時間。Android上面不帶參數,所以熄屏之後就不會再點亮螢幕了。 java driver.lockDevice(1000); // iOS driver.lockDriice(); //Android

 

2、當前Activity(Android only)

方法:currentActivity()

得到當前應用的activity。只適用於Android。 例(通訊錄): Java String ca = driver.currentActivity(); System.out.print(ca); -------------輸出結果爲------------- .activities.PeopleActivity

 

3、收起鍵盤

方法:hideKeyboard()

收起鍵盤,這個方法很有用,當我們對一個輸入框輸入完成後,需要將鍵盤收起,再切換到一下輸入框進行輸入。 Java driver.hideKeyboard(); //收起鍵盤

 

4、滑動

方法: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);

 

5、拉出檔案

方法:pullFile()

從裝置中拉出檔案。

例: Java driver.pullFile('Library/AddressBook/AddressBook.sqlitedb')

 

6、推播檔案

方法: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);