Appium使用のhelloworld

我啥時候說啦jj發表於2017-12-28

Demo 官網

最近突發興趣,想了解點測試方面的內容,同時自己又屬於比較懶的,所以期望可以做成自動化測試,寫個指令碼自動執行,在版本迭代後做迴歸測試會比較方便,另外,我期望測試框架可以根據id等屬性來定位控制元件,而不是如monkeyRunner那樣通過座標來定位,以便於測試不同機型,找了幾個框架後最後決定先試試appium, 因此就有了這篇文章;

基於: 系統: win10 64 Appium: AppiumForWindows_1_4_16_1 指令碼: python 3.5

優點(摘自<騰訊Android自動化測試實踐>):

  1. 支援多種應用程式測試: Native app(ios/android), hybrid app 和 web app
  2. 不需要被測應用做特殊修改:不需要引入任何額外的測試sdk,不需要新增其他許可權,不需要修改簽名等...(不過我安裝的時候發現會安裝兩個小程式,影響不大)
  3. 對測試指令碼的語言不做限制(比較喜歡這樣的跨平臺跨語言的,遷移方便)
  4. 支援應用間互動測試

缺點

就是執行有點慢啊... 好像沒看到直接截圖對比功能,不過可以考慮使用現成的monkeyRunner的,沒測試過...

安裝:

網上文章應該蠻多的,據說安裝比較複雜,我因為之前開發的時候安裝過androidSDK,python,node,framework4.5等等,所以一路都還挺順利,安裝過程:

  1. 在系統環境變數中配置 ANDROID_HOME 變數
  2. 安裝python並新增到path環境變數中
  3. 安裝node(非必需)
  4. 下載appium 並安裝,推薦1.4.0以後的版本
  5. 安裝appium客戶端:
pip install robotframework-appiumlibrary
複製程式碼
  1. 在開始選單中點選執行appium伺服器

指令碼編寫

  1. 設定預設編碼
# -*- codeing: utf-8 -*-
# 這個最好還是養成習慣,之前使用monkeyRunner的時候就是沒設定utf-8,執行的時候連註釋中的中文都報錯
# 匯入所需包
import sys,os,unittest
from time import sleep
from appium import webdriver
複製程式碼
  1. 設定desired capabilities鍵值對,主要用於通知 Appium 伺服器建立需要的session
'''
python 3.5
測試機型: 紅米1s android 4.4.4 
直接執行指令碼即可
'''
desire_caps = {}
desire_caps['platformName'] = 'Android'
desire_caps['platformVersion'] =  '4.4.4'
desire_caps['appPackage'] ='com.android.contacts' 
desire_caps['appActivity'] = '.activities.PeopleActivity'
# 手機名稱,這個可以通過命令列adb devices即可獲取,我發現在連線多臺手機時會有影響
desire_caps['deviceName'] = '9de1f8c7'
# 以下兩項主要是在點選輸入框的時候,會觸發系統輸入法,導致可能我們傳送的是字元 `234`,但是九宮格中文輸入法有可能給出的是 `bei` ,這兩個屬性就是遮蔽系統輸入法,使用appium自己的,但是測試完成後,得自己去系統設定中將輸入法切換過來
desire_caps['unicodeKeyboard'] = True
desire_caps['resetKeyboard'] =  True
複製程式碼
  1. 連線appium
# ip地址在pc上的 appium客戶端-設定 中可以看到 `server address` 和 `port`,保持一致即可
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desire_caps)
複製程式碼
  1. 控制元件操作
# 通過id查詢控制元件
# 具體的控制元件id可以通過 `AndroidSDK\tools\uiautomatorviewer.bat` 來直接獲取
createContactBtn = driver.find_element_by_id('com.android.contacts:id/fab')
# 模擬點選操作
createContactBtn.click()
# 也可以通過文字查詢控制元件,並輸入姓名
name = driver.find_element_by_name(u"姓名") # "姓名" 是輸入框的hint值
name.click()
name.send_keys("阿冏Lynxz") # 輸入指定的文字,注意這裡需要上面desire_caps遮蔽系統輸入法才行
# 也可以查詢多個控制元件
# 比如通訊錄可能有多個電話號碼輸入框 `elements` 多了個s
phone = driver.find_elements_by_name(u"電話")
phone[0].click()
phone[0].send_keys("189***0620")
# 判斷結果是否符合預期,不通過的話會在這裡中斷並列印日誌
# self.assertEqual(phone[0].text,"15390")
# 截圖,會在當前目錄儲存指定檔名的圖片
driver.save_screenshot("after_input.png")
# 等待,單位:秒
sleep(5)
# 測試完成,退出
driver.quit()
複製程式碼

控制元件屬性/操作方法:

  • text 控制元件顯示的文字資訊,如 edt.text,有點類似於屬性獲取
  • click() 模擬控制元件點選操作,如btn.click
  • clear() 清除控制元件的文字
  • is_enabled() 判斷控制元件是否可用
  • is_selected() 控制元件是否被選中
  • is_displayed() 控制元件是否顯示
  • get_attribute(self,name) 指定屬性名稱,返回屬性值,若屬性名不存在,則返回none
  • send_keys(self,*value) 模擬輸入文字到控制元件

系統API

  • current_activity 獲取當前activity資訊,可以直接列印,如 print(driver.current_activity)
  • current_context \ context 我在真機上測試的時候都是返回 NATIVE_APP
  • install_app(self,app_path) 安裝應用app
  • is_app_installed(self,bundle_id) 在android中傳入包名即可
  • get_screenshot_as_file(self,filename) 傳入要儲存的路徑和檔名,可以使用相對路徑
  • save_screenshot(self,filename) 跟上一條的功能類似
  • network_connection 檢視當前網路資訊,整數值, ==!測試出來都是1

效果

碰到的問題:

1. Could not extract PIDs from ps output...

selenium.common.exceptions.WebDriverException: Message: A new session could not be created. (Original error: Could not extract PIDs from ps output. PIDS: [], Procs: ["bad pid 'uiautomator'"])
複製程式碼

修改 Appium\node_modules\appium\node_modules\appium-adb\lib\adb.js 檔案

this.shell("ps '" + name + "'", function (err, stdout) {
    ...
    var procs = [];
    var outlines = stdout.split("\n");
    outlines.shift() //新增這行
    ...
複製程式碼

儲存後,重新執行appium即可

2. 500 Internal Privoxy Error

好吧,這個是我電腦上開著 shadowsocks,雖然是pac模式,但是appium就是會報錯,關閉就好了

3. 使用 send_keys() 時會觸發輸入法,導致輸入異常,中文無法輸入

Python Appium實現中文輸入分享 解決方法: 在 desire caps 引數中新增如下兩個欄位:

desire_caps = {}
...
desire_caps['unicodeKeyboard'] = True # 使用unicodeKeyboard的編碼方式來傳送字串
desire_caps['resetKeyboard'] =  True # 將鍵盤給隱藏起來
複製程式碼

當然,這樣測試結束後,發現自己輸入法呼叫不出來,可以到系統設定中切換一些輸入法(此時,預設呼叫的是Appium Android Input manager...)

相關文章