一.Appium框架組成

Appium框架組成是自動化腳本即client端(通過Java編寫的代碼,也可以通過其他語言編寫),Appium指令服務器,sdk通信環境(**Android**模擬器)或移動端設備(這里是**測試****Windows**平臺的設備,)。
? 二.Appium通信原理:
Appium通信原理:Client端發送自動化指令給Appium?**server**,Appium Server接收到client發送的指令后,轉換為移動端能夠識別的指令,然后發送給移動端設備,并對移動端設備進行操作。
2.1 Client端:
一般來說就是運行代碼的機器,即我們是用Java語言編寫的代碼,也可以用其他**Selenium**支持**Python**,ruby,C#等語言來編寫,Appium提供的Appium-client API是Appium通過擴展Selenium的Webdriver協議而來的,我們編寫代碼的時只要實現Webdriver標準協議即可。
? 2.2 Appium Server:
Appium Server功能是監聽接口,接收client端發送的command,然后將command轉為移動端能夠識別的command,然后發送給移動設備進行操作,再等待移動設備返回來的操作結果,將操作結果發送給client端。 Appium server是可以放在client端,也可以放在云端。 Appium server 默認的端口號是4723,用于Appium server監聽client端的發送來的請求。
2.3 Android設備
? ? ?Android端,Appium基于Webdriver協議,利用Bootstrap.jar,最后通過調用UIautomatior命令,實現APP的自動化測試(Android4.2以前的版本是用Instrumentation框架,通過綁定另外一個獨立的selendroid項目來實現),Android4.2以后的版本是用UIautomator)。UIAutomator測試框架是Android SDK自帶的APP UI自動化測試Java庫,另外UIAutomator對H5支持有限,Appium引入了Chromedriver以及Safaridriver來實現H5的自動化。
在Android設備的**工作**過程:
? 1.Appium server將監聽到的4723端口的指令,轉發給中間件Bootstrap.jar,Bootstrap.jar是用Java編寫的,安裝在Android手機上;
? 2.Bootstrap監聽4724端口并接收Appium server的指令;
? 3.Bootstrap再通過調用UIautomator的命令來實現具體的command操作。
? 4.最后Bootstrap將執行的結果返回給Appium server。
三、appium的整體架構是C/S模式,整體流程(返回順序為逆向):
腳本請求 ——> 4723端口appium server ——> 解析參數給PC端4724端口 ——> 發送給設備4724端口 ——>?通過設備4724端口發給bootstrap.jar ——>?Bootstrap.jar把命令發給uiautomator

1、腳本請求 ——> 4723端口appium server :
首先我們要開啟appium服務,即Appium server,**默認監聽4723端口**。4723端口專門和腳本打交道,基于WebDriver協議。webdriver是按照server – client的經典設計模式設計的,作用就是啟動基于WebDriver Wire協議的appium服務,接下來**腳本與appium server的通信實際上是一個HTTP request請求給appium server**,在請求的body中,會以WebDriver Wire協議規定的**JSON**格式的字符串來告訴appium服務我們希望設備接下來做什么事情。
appium中的Json wire protocol繼承自selenium的webdriver wire protocol,并進行了擴展,使得Json wire protocol能夠控制不同的移動設備的行為。
上面說到的是腳本請求對設備進行操作,但前提是,我們要對誰進行操作測試呢?這里就引入一個新名詞:**desired Capabilities**。了解了上述之后,再去看腳本怎么將desired Capabilities傳遞給appium server就明白多了,**腳本通過Json Wire Protocol協議以json格式發送測試設備信息給server端,測試設備信息被攜帶在Desired Capabilities中**,這個東西實質上是一個key-value形式的對象,Desired Capabilities最重要的作用是告訴server本次測試的上下文。這次是要進行瀏覽器測試還是移動端測試?如果是移動端測試的話是android還是ios?如果android的話我們要測試哪個app?server的這些疑問Desired Capabilities都必須給予解答,否則server不買賬,針對我們現在所說的安卓,它帶來的影響就是無法完成app的啟動。
那么,將測試設備信息告知之后,是不是就可以開始進行測試了呢?答案是:NO。這里又要引入一個名詞:session。session就是一個會話,在webdriver/appium,你的所有工作永遠都是在session start后才可以進行的。client 創建1個session,在該session中通過http向appium server發送請求,appium server解析請求,完成相應操作并返回response。

Session在計算機中,尤其是在網絡應用中,稱為“會話控制”。**Session 對象存儲特定用戶會話所需的屬性及配置信息,對應到這里其實就是desired Capabilities中的配置信息參數**。腳本通過POST? ? /session這個URL,然后***傳入Desired Capabilities*****就可以開啟session**了,由于這是**第一次請求創建session**,所有**并沒有一個已創建的session id**,**所以appium server會調用android driver**(appium升級到2.0.0后,原有的AppiumDriver函數變成抽象函數了,需更改為AndroidDriver)為client生成一個session并且**生成一個與此session相關聯的session id**,這個 session id將被在本次響應中返回**給客戶端保存**,當下次腳本發出操作請求時就會自帶session id為唯一標識,代表所打開的設備,Appium server會按照此session id把這個session檢索出來使用,腳本向appium server發送的請求即是存在于創建的session中的。
Session 的作用就是它在appium服務上保持設備的狀態信息,供在任何時間進行訪問,在多次的操作行為中,存儲在 Session對象中的配置信息將不會丟失,而是在整個用戶會話中一直存在下去,整個測試進程中設備與程序的聯系不會斷開,也不需要每次都發送帶配置信息的請求,程序都知道對哪個設備進行測試操作。**當測試結束后,需關閉webdriver,driver.quit()會關閉所有關聯窗口和session,并且也會把進程也關閉**。
2、解析參數給PC端4724端口 ——> 發送給設備4724端口 ——>?通過設備4724端口發給bootstrap.jar ——>?Bootstrap.jar把命令發給uiautomator:
創建session成功之前,就已將bootstrap.jar放入手機中,并開啟設備上的基于appium bootstrap的socket服務,綁定本機和boostrap通信的端口號4724用于和Android設備通訊,默認監聽4724端口,等待client的連接。
Appium server將腳本的請求解析后給到4724端口,通過設備的4724端口轉發解析后的請求, 此時,對于socket服務來說,appium server就充當了client的角色,appium server通過4724端口主動去請求設備上的socket服務,即向socket服務發送請求,即bootstrap.jar,Bootstrap.jar再把Appium的命令轉換成uiautomator的命令來讓uiautomator進行處理。有請求就有返回,socket接收到請求后會做出響應,原路返回給腳本,然后腳本再進行下一次的請求。
網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。appium和手機的通信過程,主要是數據交換的一個過程,socket的作用是就是為了實現雙向通信,它需要一對端口號,對應到這里就是4724,手機端的bootstrap就是socket-server端,appium server就是socket-client端。
關于socket的通信原理,先從服務器端說起。服務器端先初始化Socket,然后與端口綁定(bind),對端口進行監聽(listen),調用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然后連接服務器(connect),如果連接成功,這時客戶端與服務器端的連接就建立了。客戶端發送數據請求,服務器端接收請求并處理請求,然后把回應數據發送給客戶端,客戶端讀取數據,最后關閉連接,一次交互結束。
四、**Appium理念**
Appium實現自動化測試需要遵循以下四個理念:
(1)實現自動化測試時,不必重新編譯或者以任何方式修改app;
(2)編寫或運行測試case的時候可以使用多種語言;
(3)一個自動化測試框架不需要重造輪子;
(4)無論在精神上還是實踐上,自動化框架都是開源的
五、**Appium設計**
使用如下方案來遵循以上四個理念:
(1)使用供應商提供的測試框架滿足理念1
iOS: [**蘋果**](javascript:;)的 UIAutomation。
[**Android**](javascript:;) 4.2+: [**Google**](javascript:;)的 UiAutomator。
Android 2.3+: Google的 Instrumentation.(Instrumentation通過綁定一個獨立的Selendroid來提供支持)。
(2)使用供應商提供的統一的框架API,即WebDriver API滿足理念2
WebDriver(也叫[**Selenium**](javascript:;) WebDriver)指定了一個服務端/客戶端協議(也加JSON Wire Protocol),基于這個協議,使用任何語言編寫的客戶端都可以向服務端發送合適的HTTP請求。也就是說你可以選擇你喜歡的語言來編寫測試運行器或測試框架。
(3)同樣使用WebDriver來滿足理念3
事實上,WebDriver已經是網頁瀏覽器自動化測試的標準,也是W3C的工作草案,所以沒有必要為移動測試建立一套新的標準,只需要基于WebDriver協議擴展新的API來方便移動自動化測試即可。
(4)很明顯滿足了理念4,當我們讀到這邊[**文章**](javascript:;)的時候就是因為Appium是開源的。
連接參數:
```
{
"deviceName": "127.0.0.1:62001",
"platformVersion": "7.1.2",
"platformName": "Android",
"automationName": "UiAutomator2",
"appPackage": "com.cn.daming.deskclock"
}
```