成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Appium在Android UI測試中的應用實踐

移動開發 Android
UI Automator Viewer 是 Android 官方的 UI 定位工具,位于 sdk/tools 下。運行后會打開 viewer 界面。點擊獲取按鈕即可獲取當前正在運行的 Activity 的 UI 結構。

 Android 測試工具與 Appium 簡介

Appium 是一個 C/S 架構的,支持 Android/iOS Native, Hybrid 和 Mobile Web Apps 的測試框架,與測試程序通過 Selenum Webdriver 協議通訊。Webdriver 的好處是通過 HTTP RPC 的方式調用 Server 上的過程,編寫測試腳本不受語言的限制,無論是 Python, Java, NodeJS 均可以方便的編寫測試。本文中將使用 Python 進行編程。

起因是因為市場部的同事拋來如下需求:批量添加一些微信好友。直接抓取請求進行重放的方法是不靠譜的,微信與服務端的通訊均加密,Pass??紤]使用 xposed 等框架 hook 相關函數進行操作。但是 xposed 需要越獄,且開發復雜,Pass。后來想到了使用 UI 測試工具進行模擬操作,開發較為簡單。

Android UI 測試工具有很多種,如 Monkey, UIAutomator, Selendroid, Robotium 等。其中 UIAutomator, Monkey, Selendroid 均為非侵入式的 UI 測試,也就是不需要修改源代碼,只要安裝了目標程序就可以進行測試。Robotium 需要與源碼一同編譯測試。Appium 實際上就是一個測試工具的統一調度軟件,將不同的非侵入式測試工具整合在一起,對外提供統一的 API。在 Android 2.3 以前的版本,Appium 會調用 Selendroid ,之后的版本會直接使用 UIAutomator,iOS 下使用 UIAutomation。Appium 還支持 FirefoxOS 的 UI 測試。

安裝 Appium

官網給出了命令行下的安裝方法。但實際上 Appium 有 GUI 版本,更適合在 Windows/MacOS 下使用。Windows 下需要安裝 .NET Framework。

  1. > brew install node      # get node.js 
  2. > npm install -g appium  # get appium 
  3. > npm install wd         # get appium client 
  4. > appium &               # start appium 
  5. > node your-appium-test.js 

Appium 需要依賴 Android SDK 編譯在手機端運行的兩個插件,因此需要首先安裝相應的 Android SDK 版本。這里直接使用了 Android Studio 中自帶的 SDK Manager。在 SDK Manager 中選擇和測試機相對應的 SDK Platform 和較新的 Build-tools,如果需要使用模擬器測試還要裝對應的 ARM/x86 System Image,以及 Intel HAXM Installer,用于加速 x86 虛擬機。Appium 使用 adb 來與目標機器通訊,因此對于真機和模擬器操作幾乎都是相同的,如何建立模擬器在此不再贅述。

安裝完成后需要在 Appium GUI 中配置 Android SDK 目錄,隨后選擇 Android,點擊 Launch 就可以啟動 Appium Server。

Appium Server 默認會監聽 http://localhost:4723 ,用于 RPC 通訊。下面我們就可以打開熟悉的編程環境,編寫 UI 測試用例了。這里使用 Python 進行編寫,需要先安裝 Appium 的 Python Client ,然后再 python 中使用 appium.webclient 就可以連接 Appium server了。

  1. pip install Appium-Python-Client 

使用 Appium 進行 UI 控制

根據注釋修改相應屬性后即可運行測試。手機需要打開 ADB 調試,執行完以下代碼后,Appium 會在手機上安裝 Appium Settings 和 Unlock 兩個程序,隨后微信會被啟動。

  1. from appium import webdriver 
  2.  
  3. desired_caps = {} 
  4.  
  5. desired_caps['platformName'] = 'Android' #測試平臺 
  6.  
  7. desired_caps['platformVersion'] = '5.1' #平臺版本 
  8.  
  9. desired_caps['deviceName'] = 'm3_note' #設備名稱,多設備時需區分 
  10.  
  11. desired_caps['appPackage'] = 'com.tencent.mm' #app package名 
  12.  
  13. desired_caps['appActivity'] = '.ui.LauncherUI' #app默認Activity 
  14.  
  15. dr = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) #啟動Remote RPC 

Selenum Webdriver 使用了一種類似于 JS 中的 DOM 模型的方法來選擇頁面中的元素。dr 為當前正在活動的 activity 對象,可以使用 findElementByXXX 的方法來獲取 Activity 中的元素。所有 Element 后帶 s 的函數,均獲得所有匹配的元素,不帶 s 的函數獲得***個匹配的元素。

查詢函數

1. findElement(s)ByName

在 Android 中基本沒用。Android UI 沒有 Name 這個屬性。有說可以使用 text 值獲取。但我并沒有成功

2. findElement(s)ByClassName

通過類名來獲取元素,用法如下:

  1. item_list = dr.find_elements_by_class_name("android.widget.LinearLayout"
  2. item_list[2].click() 

3. findElementById

通過 resource_id 來獲取元素,每個 Activity 中都是***的,用法如下

  1. t = dr.find_element_by_id("com.tencent.mm:id/f7"
  2. t.send_keys(wechatId) 

4. findElement(s)ByAccessbiltiyId

在 Android 上 AccessbilityID 實際就是 contentDescription 。這個屬性是為了方便視力受損人士使用手機所設置。開啟 TTS 后系統會朗讀相關控件的 contentDescription。

5. findElement(s)ByXPath

通過 XML Path 描述來尋找元素。我沒有成功的獲取到,可能是 XPath 寫的有問題。

  1. s = dr.find_element_by_xpath("//android.widget.TextView[contains(@text,'搜索')]"
  2. s.click() 

6. findElementByAndroidUIAutomator

通過 UIAutomator 的選擇器來獲取元素。因為 Appium 在 Android 上實際是調用的 UIAutomator,所以可以通過 UIAutomator 的選擇器來選擇元素。

  1. el = dr.find_element_by_android_ui_automator("new UiSelector().text(\"搜索\")"
  2. el.click() 

操作函數

操作函數用于操作選定的元素,有很多,以下僅列舉幾個,更多的請查閱手冊。

  • click
  • send_keys
  • clear

查詢函數返回的元素對象可以像 JS 中的 dom 元素一樣,繼續使用查詢函數來選定其子元素。用例如下。

  1. search = dr.find_element_by_id("com.tencent.mm:id/aqw").find_element_by_class_name("android.widget.RelativeLayout"
  2.  
  3. search.click() 

如何確定查詢規則

了解了相關的函數后,下面就應對 UI 進行定位了。如果是自己團隊開發的程序,推薦讓開發同學在所有的空間上都添加 resource_id 進行絕對定位。如果碰到沒有談價 resource_id 的元素,那就要使用別的辦法進行定位了。

1. UI Automator Viewer

UI Automator Viewer 是 Android 官方的 UI 定位工具,位于 sdk/tools 下。運行后會打開 viewer 界面。點擊獲取按鈕即可獲取當前正在運行的 Activity 的 UI 結構。

2. AppiumDriver getPageSource

AppiumDriver(Client) 可以很方便的獲得當前正在運行的 Activity 的 UI 描述,隨后可根據返回的 XML 文檔來尋找元素。

  1. print dr.page_source 

確定元素位置后,即可根據前述的 Find 方法來查找/選擇元素

編寫完整的測試代碼

正確的獲取元素之后便可以獲取元素相關的信息,隨后使用各語言常用的測試框架編寫測試即可,如 Java 的 JUnit,Nodejs 的 Mocha 等。

這里我使用 Appium 主要是為了模擬用戶點擊添加微信好友,所以完整的程序并沒有使用到測試框架。相關的 UI 元素獲取/操作方法供大家參考。

  1. # coding:utf-8 
  2. from appium import webdriver 
  3. from time import sleep 
  4.  
  5.  
  6. def addFriend(dr, id, dryRun=False): 
  7.     succ = False 
  8.     wechatId = str(id) 
  9.     dr.find_element_by_accessibility_id(r"更多功能按鈕").click() 
  10.     item_list = dr.find_elements_by_class_name("android.widget.LinearLayout"
  11.     try: 
  12.         item_list[2].click() 
  13.     except
  14.         print "Error! in item list len" 
  15.         return succ 
  16.     el = dr.find_element_by_class_name("android.widget.ListView"
  17.     item_list = el.find_elements_by_class_name("android.widget.LinearLayout"
  18.     try: 
  19.         item_list[1].click() 
  20.     except
  21.         print "Error! in item list len" 
  22.         return succ 
  23.     t = dr.find_element_by_id("com.tencent.mm:id/f7"
  24.     t.send_keys(wechatId) 
  25.     search = dr.find_element_by_id("com.tencent.mm:id/aqw").find_element_by_class_name("android.widget.RelativeLayout"
  26.     search.click() 
  27.     try: 
  28.         freq = dr.find_element_by_id('com.tencent.mm:id/aqq'
  29.         assert freq.text == u"操作過于頻繁,請稍后再試。" 
  30.         print "Frequency too high! Sleep 300s" 
  31.         sleep(60) 
  32.         return succ 
  33.     except
  34.         pass 
  35.  
  36.     try: 
  37.         dr.find_element_by_id('com.tencent.mm:id/a8x').click() 
  38.         addBtn = dr.find_element_by_id('com.tencent.mm:id/eu'
  39.         if not dryRun: 
  40.             addBtn.click() 
  41.             succ = True 
  42.         print "Success Send Requests:" + wechatId 
  43.     except
  44.         print "No Such User Or Already a Friend:" + wechatId 
  45.  
  46.     while True
  47.         try: 
  48.             dr.find_element_by_id('com.tencent.mm:id/fb').click() 
  49.         except
  50.             try: 
  51.                 dr.find_element_by_id('com.tencent.mm:id/f4').click() 
  52.             except
  53.                 break 
  54.     return True 
  55.  
  56. def resetActivity(dr, desired_caps): 
  57.     dr.start_activity(desired_caps['appPackage'], desired_caps['appActivity']) 
  58.  
  59. desired_caps = {} 
  60. desired_caps['platformName'] = 'Android' 
  61. desired_caps['platformVersion'] = '5.1' 
  62. desired_caps['deviceName'] = 'm3_note' 
  63. desired_caps['appPackage'] = 'com.tencent.mm' 
  64. desired_caps['appActivity'] = '.ui.LauncherUI' 
  65. print "Trying connect to phone..." 
  66. dr = {} 
  67. try: 
  68.     dr = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) 
  69. except Exception, e: 
  70.     print "Cannot Connect to phone :", e 
  71.     exit() 
  72. print "Successfully connect to phone." 
  73. print "Reading friend list..." 
  74. friendList = [] 
  75. fp = open("friends.txt"
  76. line = fp.readline().strip() 
  77. while line: 
  78.     friendList.append(line) 
  79.     line = fp.readline().strip() 
  80. print "Finish reading friends. Total: " + str(len(friendList)) 
  81. print "Wait for Wechat's splash screen...." 
  82. for i in range(0, 10): 
  83.     print 10 - i 
  84.     sleep(1) 
  85. succ_list = [] 
  86. fail_list = [] 
  87. for i in friendList: 
  88.     try: 
  89.         succ = addFriend(dr, i, dryRun=False
  90.         if succ: 
  91.             succ_list.append(i) 
  92.         else
  93.             fail_list.append(i) 
  94.     except
  95.         fail_list.append(i) 
  96.         resetActivity(dr, desired_caps) 
  97.  
  98. print "Succeed List:" 
  99. print "\n".join(succ_list) 
  100. print "Failed List:" 
  101. print "\n".join(fail_list) 
  102.  
  103. dr.close() 

 【編輯推薦】

責任編輯:武曉燕 來源: segmentfault
相關推薦

2021-10-18 12:01:17

iOS自動化測試Trip

2014-08-08 16:50:21

AB 測試安卓推送

2017-05-22 08:05:46

HBase阿里搜索實踐

2022-05-30 07:48:11

DevOps測試策略

2012-07-09 10:13:06

ibmdw

2024-09-25 10:10:35

2021-08-03 12:58:38

鴻蒙HarmonyOS應用

2011-04-18 12:52:37

自動化測試功能測試軟件測試

2012-05-08 16:40:36

Android

2024-04-07 07:53:12

SpringWeb技術WebSocket

2014-03-24 13:39:51

2019-11-26 18:00:59

系統運維架構

2018-08-30 09:00:00

開源Apache Kafk數據流

2019-04-09 15:02:36

OpenResty騰訊游戲營銷技術

2024-04-08 07:28:27

PiniaVue3狀態管理庫

2024-06-04 07:29:13

2022-04-08 09:01:56

腳本Go應用單元

2022-10-14 16:18:40

MobileNetAndroid端模型訓練

2020-07-08 10:01:07

SDP網絡安全安全框架

2010-10-16 15:46:49

動態更新UIAndroid
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产一级一级 | 欧美国产精品一区二区三区 | 男女网站在线观看 | 国产在线拍偷自揄拍视频 | 中文字幕在线免费观看 | 91精品国产91久久久久青草 | 亚洲精品在线播放 | 一区二区三区亚洲 | 91精品国产乱码久久久久久久 | 日韩久久久久久 | 黄色免费在线观看网站 | 欧美成人一区二区 | 7777久久 | 麻豆国产精品777777在线 | 91福利网| 亚洲午夜视频在线观看 | 久久伦理电影 | 久久国产精品视频 | 干干天天 | 中文字幕丁香5月 | 亚州精品天堂中文字幕 | 精品久久久久久久久久久久久久 | 亚洲欧美日韩一区二区 | 成人国产免费视频 | 国产在线观看av | 日本精品视频在线观看 | 久久亚洲一区 | 精品av久久久久电影 | 国产一区二区精品自拍 | 欧美精品久久久 | 久久久综合精品 | 99久久免费精品国产男女高不卡 | 亚洲成人精品国产 | 精品在线观看一区二区 | 在线观看国产精品一区二区 | 亚洲欧美日韩成人在线 | 一区二区高清在线观看 | 国产一区二区三区精品久久久 | 国产中文在线 | 欧美激情久久久 | 日韩精品一区中文字幕 |