App自動化測試工具Airtest
AirtestProject是由網易遊戲推出的一款跨平臺的UI自動化測試框架,主要是面向遊戲的UI自動化測試,比如Unity3D、cocos2dx-*遊戲框架,也支援Android原生app、iOS app、微信小程式的UI測試。本文主要介紹如何使用AirtestProject進行Android APP自動化測試。
目錄AirtestProject元件
AirtestProject包括一下元件:
- Airtest:基於影象識別的自動化測試框架,適用於遊戲和App,影象識別主要使用opencv庫。專案地址:https://github.com/AirtestProject/Airtest
- Poco:基於UI元素識別的測試框架,支援Unity3D/cocos2dx-*/Android原生app/iOS原生app/微信小程式。專案github地址:https://github.com/AirtestProject/Poco
- AirtestIDE:圖形介面,內建了Airtest和Poco的相關外掛。官網地址:http://airtest.netease.com/
- AirLab:真機自動化雲測試平臺。
下面介紹如何使用Airtest和Poco進行自動化測試。
下載安裝
先安裝一下AirtestIDE,主要用於截圖、UI 元素檢視以及指令碼除錯,下載地址:http://airtest.netease.com/
下載完成後解壓,開啟AirtestIDE.exe檔案,連線一個模擬器,模擬器頁面會實時顯示在右邊:Python安裝:
pip install -U airtest # airtest測試框架 pip install pocoui # poco測試框架
Airtest使用
安裝解除安裝apk
install("path/to/your/apk") # 安裝APK
uninstall("package_name_of_your_apk") # 解除安裝APK
連線裝置
init_device(platform="Android",uuid="SNHVB20C18002195") # 連線android裝置SNHVB20C18002195
init_device(platform="Windows",uuid="29563034") # uuid表示Android裝置的序列號,Windows的控制代碼,iOS的uuid
connect_device('Android:///') # 本地android裝置
connect_device('Android:///SNHVB20C18002195') # SNHVB20C18002195為手機序列號,可通過adb devices命令檢視
connect_device("Android://127.0.0.1:7555")
connect_device("Windows:///") # 連線到windows桌面
connect_device("Windows:///29563034") # 連線到控制代碼29563034的windows應用
connect_device("iOS:///127.0.0.1:8100") # 連線iOS 裝置
開啟、停止APP
開啟APP
start_app(package, activity=None)
停止APP:
stop_app(package)
元素操作方法
常用的元素操作方法主要包括下面5種:
### touch點選操作touch((100, 100), times=1) # 點選絕對座標,times為點選次數,預設為1次
touch((100, 100), duration=2) # Android 和 Windows 平臺應用可設定點選時間duration
touch((100, 100), right_click=True) # Windows右鍵點選
touch(Template(r"tpl1624889731448.png", record_pos=(-0.129, 0.832), resolution=(720, 1280))) # 點選圖片中心,Template類包括了圖片位置,手機解析度,圖片儲存位置屬性以及模板匹配,查詢圖片在手機的位置等方法
圖片可以通過AirtestIDE來獲取,點選Airtest輔助窗的touch方法,然後在裝置窗中選擇要操作的位置區域:
swipe滑動操作
swipe(v1, v2, vector=None) # 從v1滑動到v2,v1為起點,可以是Template類或者畫素座標
swipe((341,297), vector=[0.0131, 0.2495])
swipe(Template(r"tpl1624977188003.png", record_pos=(-0.015, -0.204), resolution=(720, 1280)), vector=[0.0011, 0.2826])
text文字輸入
使用此方法時要確保輸入框為活動狀態,可以先點選一下輸入框,然後再輸入
text("test", enter=True) # 輸入完成後,輸入Enter鍵
keyevent鍵盤輸入
keyevent(keyname) # 在Android中類似於執行 adb shell input keyevent KEYNAME
keyevent("HOME") # 或者 keyevent("3") HOME鍵
Android的按鍵可參考:https://developer.android.com/reference/android/view/KeyEvent
snapshot截圖
snapshot(filename=None, msg="", quality=None, max_size=None) # 儲存螢幕截圖,filename:影象名,quality:影象質量(1-99),max_size:大小
wait等待出現
等待目標圖片出現
wait(Template(r"tpl1624977188003.png"), timeout=None, interval=0.5, intervalfunc=None) # timeout:最大等待時間,interval:檢查間隔時間
exists檢查目標是否出現
檢查當前介面是否出現指定目標
pos = exists(Template(r"tpl1624977188003.png")) # 如果找到目標,可以返回目標位置座標
if pos:
touch(pos)
斷言
斷言目標是否存在
斷言目標存在:assert_exists
assert_exists(Template(r"tpl1624977188003.png"))
斷言目標不存在:assert_not_exists
assert_not_exists(Template(r"tpl1624977188003.png"))
值是否相等
assert_equal(first, second) # 斷言兩個值相等
assert_not_equal(first, second) # 斷言兩個值不相等
Poco使用
UI 元素可通過在AirtestIDE的Poco 輔助窗檢視:
## poco初始化Android手機開啟開發者模式,連線電腦,通過adb devices
檢視手機是否連線成功。
初始化:
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(force_restart=False,use_airtest_input=True, screenshot_each_action=False)
poco.device.wake() # 執行喚醒:進入主頁,啟動Yosemite
UI元素定位
基本選擇器
poco('node_name') # 預設第一個引數為節點名
# 也可以通過name 或者其它屬性定位
poco(text='行情', type='android.widget.TextView')
相對選擇器
和XPath的相對定位一樣,poco可以根據父子關係、兄弟關係、祖孫關係來定位。
子節點和子孫節點定位:# select by direct child/offspring
poco("android:id/tabs").child("android.widget.RelativeLayout")[1].offspring(text="行情").click() # 具有多個元素的情況下,可以使用索引,索引從0開始。
兄弟節點定位:
poco("name").sibling("sibling_name")
父節點:
poco("name").parent("parent_name")
屬性獲取
獲取UI物件屬性
ele = poco(text='行情')
print(ele.attr('type')) # 屬性
print(ele.attr('text')) # text屬性
print(ele.get_bounds()) # 邊界框
print(ele.get_position()) # 座標
print(ele.get_size()) # UI 元素大小
print(ele.get_name()) # 元素名稱
print(ele.get_text()) # 元素文字值,和ele.attr('text')一樣
print(ele.exists()) # 元素是否存在
執行結果:
android.widget.TextView
行情
[0.978515625, 0.39583333333333337, 0.994921875, 0.3541666666666667]
[0.375, 0.98671875]
[0.041666666666666664, 0.01640625]
com.xueqiu.android:id/tab_name
行情
True
poco中的座標採用百分比座標,將x和y方向都縮放為0-1。
UI 元素操作
下面介紹幾種常見poco元素操作方法
click點選
點選UI元素
poco('name').click() # 預設點選UI元素錨點(左上角)
poco('name').click('center') # 點選中心點
poco('name').click([0.5, 0.5]) # 點選中心點
poco('name').focus([0.5, 0.5]).click() # 點選中心點
點選座標
poco.click([0.5, 0.5]) # 點選螢幕中心點
poco.long_click([0.5, 0.5], duration=3) # 長按
set_text文字輸入
text = 'test'
poco('name').set_text(text) # 相文字框name輸入文字
swipe滑動
swipe(direction, focus=None, duration=0.5)
-
direction : 滑動方向,可選up,down,left,right,也可傳入向量座標。
-
duration:滑動持續時間,時間越短,滑動速度就越快,滑動的距離就越長
ele = poco('name')
ele.swipe('up') # 向上滑動
ele.swipe([0,-0.1]) # 向上滑動
ele.swipe('down') # [0,0.1] 下滑
ele.swipe('left') # [-0.1,0] 左滑
ele.swipe('right')# [0.1,0] 右滑
ele.swipe([0.2, -0.2]) # 右上45度角滑動swipe sqrt(0.08) 單元距離
ele.swipe([0.2, -0.2], duration=0.5)
根據座標滑動
poco.swipe(p1, p2=None, direction=None, duration=2.0)
從座標 (100, 100) 滑動到 (100, 200) ,手機螢幕解析度為1920×1080
poco.swipe([100/1920, 100/1080], [100/1920, 200/1080], duration=0.5)
# 或者
poco.swipe([100/1920, 100/1080], direction=[0, 100/1080], duration=0.5)
drag_to拖到
從一個UI元素拖到另一個UI元素
ele1 = poco('name1').focus([0.5,0.5])
ele2 = poco('name2').focus([0.5,0.5])
ele.drag_to(ele2)
wait等待
等待目標物件出現,返回目標物件
poco('name').wait(5).click() # 最多等待5秒,元素出現後點擊
poco('name').wait(5).exists() # 最多等待5秒,返回元素是否出現
poco('name').wait_for_appearance(timeout=10) # 等待元素出現
poco("name").wait_for_disappearance(timeout=10) # 等待元素消失
ele1 = poco('name1')
ele2 = poco('name2')
poco.wait_for_all([ele1,ele2], timeout=10) # 等待2個UI元素標籤全部出現
poco.wait_for_any([ele1,ele2], timeout=10) # 等待任意一個UI元素出現
截圖
from base64 import b64decode
b64img, fmt = poco.snapshot(width=720)
open('screen.{}'.format(fmt), 'wb').write(b64decode(b64img))
總結
本文主要介紹了Airtest和poco的使用方法,Airtest的圖片識別功能很好用,poco用於UI元素操作。可以將這它們結合起來使用,特別是在遊戲的測試中,需要通過圖示來定位。Airtest+poco還有一個優點就是app初始化啟動速度要快於appium。