AWS Device Farm介紹及Appium踩過的坑

       本文記錄了在AWS Device Farm上進行Appium TestNG進行手機應用UI自動化測試的流程及遇到的問題,及具體的解決方法。同時記錄了使得測試腳本更穩定的一些代碼寫法。

       Device Farm是Amazon Web Service推出的雲應用測試工具,允許你在數量衆多的物理移動設備上測試你的應用。DF提供了兩項功能。其中Remote Access允許你通過網頁遠程操控雲端的設備,並可上傳安裝自己的應用。另外Automated Tests還允許你上傳自己的自動化測試腳本,在雲端的設備上執行自動化測試。

       DF支持多種UI測試框架如:Appium Java JUnit, Appium Java TestNG, Appium Python, Calabash等。經過與JUnit的對比,最終我選擇了Appium Java TestNG。

       類似的平臺有Xamarin Test Cloud以及國內騰訊的WeTest上的雲真機。


Device Farm使用步驟:

1、本地設備上測試通過你的測試腳本

2、將腳本按照官方教程使用Maven方法打包成zip文檔

3、上傳zip以及ipa/apk,選定設備池,執行測試

4、等待執行完成,分析執行結果,修正直到全部通過

備註:

       唯一的麻煩是使用官方特定的Maven打包方式,可以直接github下官網的Demo,複製到自己的項目。



踩過的坑:

autoAcceptAlerts和autoDismissAlerts在XCUITest中被棄用了,對話框需要代碼中處理。


android:

Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator

ios:

Valid locator strategies for this request: xpath, id, name, class name, -ios predicate string, -ios class chain, accessibility id


IOS必須指定bundleId、UDID、deviceName

Android雖說deviceName沒有意義,但不指定編譯不通過


IOSDriver中沒有AndroidDriver的許多方法,例如:pressKeyCode();

對於不能獲取焦點的EditText,IOS中也能使用sendKey()來輸入文本,而Android只能使用driver.pressKeyCode(),向設備發送鍵值的方式。


對於一個列表而言:

IOS會把看不見的未顯示到當前屏幕的元素也找出來,這個時候需要使用isDisplay來判斷是否可見。

因爲不可見意味着不可點擊。而Android初步測試不會把看不見的列表元素找出來。


driver.swipe(start_x, start_y, end_x, end_y, duration);

這裏的end_x, end_y實踐證明就是目的座標,論壇上許多人說是偏移量,版本不對嗎?


有的時候findElement找不到的時候,使用findElements獲得數組,並使用對應的下標,常常可以找到。

特別是對付對話框裏的元素


appium沒有提供直接判斷是否找到元素的方法,可以用findElement方法是否拋出NoSuchElementException來判斷,或者判斷findElements返回數組的size是否爲零。


對於滾動查找列表項的操作,會發生目標項只有部分顯示就被找到的情況。這個時候如果你需要偏移座標查找如CheckBox之類的元素,有可能發生偏移後的座標超出屏幕的情況。

此時相應方向的座標需要防止越界。可以在找到後再滑動一次屏幕,以保證目標完全顯示。click操作也是如此,因爲click默認是tap元素的中心座標,而元素的中心座標可能尚未顯示。


Appium支持中文:

在Capabilities 中添加

capabilities.setCapabilities("unicodeKeyboard",true);

capabilities.setCapabilities("resetKeyboard",true);//必須

在設置上面兩個屬性後,如果腳本中途崩潰,容易出現系統輸入法被替換爲Appium輸入法的問題,該輸入法是沒有界面的。


錯誤:xcodebuild failed with code 65

解決:將WebDriverAgentRunner安裝到iphone上。方法如下

1、使用Appium Inspector建立Session成功,會自動安裝

2、運行測試代碼建立Session成功,會自動安裝

3、使用Xcode或xcodebuilder將WebDriverAgent直接安裝到設備上

4、以上都不行,則到WebDriverAgent的github官網下載最新的替代現有的


UI自動化測試具有不穩定性,任何微小的延遲或界面不同於預期,腳本就會失敗。要寫出在多種機型上正確運行的腳本,需要不少時間,如果你要結合雲測試平臺進行雲端設備的自動化測試,不穩定性會更高。所以設定合理的等待時間,在可能出現彈框的地方進行判斷。



AWS Device Farm注意:

AWS官網的文檔很可能不是最新的,比如:官網最新支持appium1.6.3, Github上最新支持appium1.6.5。官網說明項目需要修改POM.xml文件,Github上直接給出詳細步驟,對於詳細技術文檔,Github纔是王道,官網更新常常不及時。


Device Farm會把所有的JUnit Test Case轉換成TestNG Test Case。但官方說不會有影響。

實際上對於註解的支持就不一樣了,例如JUnit中的@BeforeClasss在被轉換成TestNG後是否會相當於TestNG的@BeforeClass,並且JUnit要求@BeforeClass方法必須是Public static修飾,而TestNG並無這樣的限制。所以還是改用TestNG吧,免得疑神疑鬼,況且需要改的也只是註解和稍微調整邏輯而已。


Device Farm(Appium1.6.5)已經可以重寫DesiredCapabilities覆蓋服務器。例如添加:NoReset = true。官方例子中明確寫出DesiredCapabilities必須爲空,信息不同步,那指的是1.4.3版本的appium。

(不能重寫的信息來自Github官方例子,可以重寫的信息來自stackoverflow的官方工程師答疑)


Device Farm上IOS使用driver.manage().window().getSize().getWidth();在執行getSize()的經常時候返回null,Android沒有這個問題,有時候需要用固定數值。

同樣在執行element.getLocation()時也是經常直接崩潰。後來又莫名奇妙好了,這麼不穩定,測試個球。


AWS默認每個用例執行後都會resetApp。也就是清空所有狀態。

所以如果你的app需要登錄,則每個用例執行前都需要重新登錄一遍,

方法一:可以把Login的邏輯放在JUnit的@Before或TestNG的@BeforeMethod方法裏。

方法二:設置Desired Capabilities的NoReset設爲true,讓其不要在會話前重置應用狀態


理論上本地使用Appium相同版本測試通過的代碼,放到DeviceFarm上是不應該有問題的,現實卻不是這樣。Device Farm上提供了多種記錄:Vedio、Appium Java Output、Appium Server Output、Logcat等。答案只能在這裏找了。


遠程調試遠比本地調試麻煩的多,網絡的限制,實時性的限制等。遠程調試一次花費的時間遠比本地調試來的長。並且只能通過返回的日誌信息查找問題。


千奇百怪的手機,就有千奇百怪的彈框,還有兩個平臺的適配,耐心方得始終。


Device Farm需要藉助Maven將項目打包成指定格式的zip格式,如果官網看不明白,直接上github下載官方Demo,參照它的代碼結構寫即可。主要是一個pom.xml和zip.xml。官方Demo使用Page Object的結構組織代碼,可以瞭解一下:https://github.com/SeleniumHQ/selenium/wiki/PageObjects


Device Farm允許一次測試選擇多部設備,並且是並行執行測試,如果你的腳本包含了測試登錄功能,那麼很可能出現一個賬號在多臺設備間相互踢出再登錄的情況。這時候只能一次選一臺設備單獨執行,除非能在登錄時判斷不同設備登錄不同賬號。



惱人的系統對話框

做機型適配時,最麻煩的就是系統對話框了,不同系統版本,不同廠商的權限對話框出現時機可能不同,可能多個權限對應一個對話框,也可能多個權限對應多個對話框。還有偶爾出現的其他app的對話框,這個沒轍。例如google service被登出,iTune賬號在其他平臺登錄被提出,IOS推送服務Push Notification失敗,千奇百怪,寫代碼有什麼難的,適配才難。


保證對話框位置固定後再查找元素:

對話框查找元素時使用的id,最好是包含包名的如com.hello.name:id/button1。使用button1容易找不着。


彈出對話框時,需要注意findElement操作執行之前對話框是否顯示到位(動畫效果完成),動畫執行過程中findElement獲取Element的座標不是最終的座標。所以會出現,findElement可以找到,click等交互操作沒反應的情況。同樣需要注意在對話框顯示之前等待一定時長保證軟鍵盤完全消失。


如果發現查找對話框元素時,同時查找到了對話框下onStop狀態的元素,則可能是使用findElements找數組元素時,在該元素還是onResume狀態時就找到了,而當你對其進行操作時,該元素已經onStop不可交互了。這時候可以等待一下對話框完整展示再查找。


調試系統權限對話框

系統對話框如權限對話框只有在第一次啓動App時纔會顯示,允許過後就不再顯示了。這造成適配對話框的代碼不好測試。每次測試都需要進系統權限界面把授予的權限取消或者IOS需要重新安裝ipa。可以在@AfterTest中執行driver.resetApp()將App的狀態重置。這樣每次測試的app都和重新安裝一樣。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章