AirtestIDE 初體驗

官網:http://airtest.netease.com/docs/docs_AirtestIDE-zh_CN/
其他筆記:
Airtest Project 自定義啟動器批量運行腳本
解決運行Airtest腳本時opencv-contrib-python報錯的問題
Airtest Project + Jenkins 微信小程序UI自動化測試 持續集成實踐

開發環境準備

使用AirtestIDE來編寫腳本,只需要在 官網 下載最新版本AirtestIDE,解壓即可直接使用。AirtestIDE內置了Python3.6.5,airtest和poco環境,本地無需安裝python環境就能直接使用。

如果想要使用其他需要安裝的Python第三方庫,或者Python2環境,則需要進行本地python的 環境部署 ,然后在AirtestIDE設置中添加本地的Python.exe路徑,詳情參考 IDE配置。

在AirtestIDE中新建的腳本,后綴都為 .air ,但實際上在運行的時候, 運行的是.air目錄下的同名.py文件 。

腳本調試

目前AirtestIDE暫不支持斷點調試功能,因此調試腳本只能通過print等較為簡單的方式。但是由于Airtest框架涉及到圖像識別的準確率問題,需要反復運行和調試才能確定合適的圖片與識別閾值,因此IDE特別提供了一種 選中部分代碼單獨運行 的調試功能(如下),需要注意的是,該單獨運行代碼的功能不會執行到腳本中其他代碼里的內容,可能會出現別處的變量未能初始化等情況(因此不支持poco)。

IDE還提供了一個圖片截圖預覽功能,在腳本編輯區內雙擊圖片,會彈出圖片編輯器,在圖片編輯器內點擊 Snapshot Recognition 按鈕,將會截取當前的手機屏幕畫面,并且進行一次識別,識別成功的話會在截圖上面標注出識別區域,方便進行截圖的調試。

Mac Airtest圖片編輯器疑有BUG,點擊圖片編輯器的右下角的OK或Cancel鍵后,整個IDE都會卡死,已提交Issue

目前圖片識別中,每次識別時,只要識別結果的可信度>閾值 threshold 即認為是識別通過。如果識別到錯誤的位置,可以通過調節 threshold 進行準確度調整。

Android 真機USB連接

測試機:華為

  1. 開啟開發者模式:進入設置->系統->關于手機,多次點擊版本號后進入開發者模式;

  2. 設置開發人員選項:允許USB調試、連接USB時總是彈出提示、監控ADB安裝應用、僅充電模式下允許ADB調試(可選)

  3. 關閉電腦上已經安裝的手機助手軟件, 使用USB線連接手機,手機上出現USB連接方式(傳輸照片、傳輸文件和僅充電),選擇"傳輸照片",如果在第二步中設置了僅充電模式下允許ADB調試,則需要選擇"僅充電"選項;

  4. 點擊Airtest點擊列表內對應設備的 Connect 完成連接, 若設備未刷出,點擊 refresh ADB 按鈕設備列表將會刷新;

Airtest

基于圖像識別的無侵入式測試框架。

初始化

# -*- encoding=utf8 -*-

from airtest.core.api import *
auto_setup(__file__)  #自動初始化設備

錄制airtest語句

  • 輔助按鍵錄制腳本

在AirtestIDE的Airtest錄制輔助窗內,包含有三種類型的錄制按鈕:

點擊某個按鈕后,在設備畫面上按下鼠標左鍵進行截圖框選,抬起鼠標左鍵完成框選。對應操作語句會自動插入編輯器腳本中。

  • 腳本自動錄制

點擊自動錄制按鈕后,使用鼠標操作設備畫面,對應操作語句會自動插入到編輯器腳本中(不好用)。

airtest.core.api

Airtest的常用API大部分都列在了AirtestIDE里的Airtest輔助窗中,在使用各種常見的截圖語句時,鼠標移動到按鈕上即可看到每個接口的常用參數與返回值信息,非常方便。

Poco

基于UI控件識別的測試框架

API文檔:https://poco.readthedocs.io/en/latest/source/poco.proxy.html#poco.proxy.UIObjectProxy.exists

poco.exceptions module: https://poco.readthedocs.io/en/latest/source/poco.exceptions.html

初始化

切換Poco應用類型時,腳本編輯框會彈出提示插入初始化Poco代碼的通知窗。 確認Poco應用類型正確后,確認插入光標位置后,點擊 'Yes' 即可插入對應的Poco初始化代碼。

  • Unity3D
from poco.drivers.unity3d import UnityPoco

poco = UnityPoco()
  • Android native APP
from poco.drivers.android.uiautomation import AndroidUiautomationPoco

poco = AndroidUiautomationPoco()
poco.device.wake()
poco(text='Clock').click()

切換模式

Poco Pause ->凍結模式

主要用途:查看當前畫面中各位置的UI呈現范圍。UI自動化測試中,常使用此功能進行元素定位。

進入方式:

  • 單擊UI渲染樹上的任意條目(注意是單擊,雙擊會直接將當前UI位置插入到代碼區域);

  • 點擊 Poco Pause 按鈕:

具體表現:

  • 屏幕畫面會凍結(設備操作失效),UI渲染樹的數據也會停止刷新。

  • 伴隨鼠標在畫面中的移動,對應位置的UI元素會被標記框標出。

  • 鼠標左鍵點擊,可以在log輸出窗中查看對應控件的詳細屬性。

Poco Inspect ->檢視模式

主要用途:伴隨設備操作,查看不同頁面UI的渲染情況。

進入方式:

具體表現:

  • 設備畫面可以正常交互,UI渲染樹的數據正常刷新。

  • 伴隨鼠標在畫面中的移動,對應位置的UI元素會被標記框標出。

  • 鼠標左鍵點擊,可以在log輸出窗中查看對應控件的詳細屬性。

Poco Recording ->錄制模式

  • 單步錄制Poco腳本

    如下,先通過凍結模式在UI樹中找到目標條目,雙擊直接插入poco代碼,也可以右鍵目標條目,選擇插入UI節點的Xpath代碼。

    注意:單步錄制,只會poco插入代理對象,具體的操作代碼(如 ".click()" )需要手動添加。

  • 自動錄制

    進入方式:

    具體表現:

    • 設備畫面可以正常交互,UI渲染樹的數據正常刷新。

    • 伴隨鼠標在畫面中的移動,對應位置的UI元素會被標記框標出。

    • 伴隨設備操作(點擊、滑動),即可插入對應UI節點的poco代碼。

自動錄制時,會自動插入代碼對象的操作代碼。

選擇器

在poco實例后加一對括號就可以進行UI選擇了。選擇器會遍歷所有UI,將滿足給定條件的UI都選出來并返回。括號里的參數就是所給定的條件,用屬性名值對表示,其中第一個參數固定表示 節點名 其余可選參數均表示節點的屬性及預期的屬性值。詳見: API Reference selecting UI

  • Basic Selector
# select by node name
poco('bg_mission')

# select by name and other properties
poco('bg_mission', type='Button')

# 支持正則
poco(text='確定')
poco(textMatches='^據點.*$', type='Button', enable=True)
  • Relative Selector
# select by direct child/offspring
items=poco('main_node').child('list_item').offspring('item')

# 可迭代對象
for item in items:
    item.child('icn_item')
  • Sequence Selector
tems = poco('main_node').child('list_item').offspring('item')
print(items[0].child('material_name').get_text())
print(items[1].child('material_name').get_text())

讀取屬性

mission_btn = poco('bg_mission')
print(mission_btn.attr('type'))     # 'Button'
print(mission_btn.get_text())     # '查詢停車費'
print(mission_btn.attr('text'))    # '查詢停車費' equivalent to .get_text()
print(mission_btn.exists())    # True/False, exists in the screen or not

操作對象

  • 點擊 click
    點擊默認點在 anchorPoint 上,每個UI都會有一個 anchorPoint ,也就是檢視器(Inspector)中UI包圍盒的那個紅點,大部分情況下 anchorPoint 都在UI包圍盒的正中央。如果想指定其他的點擊位置,可以傳一個參數到 click 方法中,這個參數是一個用list或tuple表示的2維向量,其 [x, y] 值分別表示相對于包圍盒左上角的偏移量,左上角為 [0, 0] ,右下角為 [1, 1]
poco('bg_mission').click()
poco('bg_mission').click('center')
poco('bg_mission').click([0.5, 0.5])    # equivalent to center
poco('bg_mission').focus([0.5, 0.5]).click()  # equivalent to above expression
  • 局部定位 focus
    所有UI相關的操作都默認以UI的 anchorPoint 為操作點,如果想自定義一個點那么可以使用 focus方法。調用此方法將返回 新的 設置了默認 焦點 的UI,重復調用則以最后一次所調用的為準。focus 所使用的是局部坐標系,因此同樣是UI包圍盒的左上角為原點,x軸向右,y軸向下,并且包圍盒長寬均為單位1。很顯然中心點就是 [0.5, 0.5] .
poco('bg_mission').focus('center').click()  # click the center
  • 滑動 swipe
    swipe操作同樣是以 anchorPoint 為起點,如果你想改變起點請使用 focus 方法,然后朝給定向量所代表的方向滑動,距離也就是向量的長度.
joystick = poco('movetouch_panel').child('point_img')
joystick.swipe('up')
joystick.swipe([0.2, -0.2])  # swipe sqrt(0.08) unit distance at 45 degree angle up-and-right
joystick.swipe([0.2, -0.2], duration=0.5)
  • 拖拽 drag
    swipe 不同的是, darg 是從一個UI拖到另一個UI,而 swipe 是將一個UI朝某個方向拖動。
poco(text='AAA').drag_to(poco(text='BBB'))```

focusdrag_to 結合使用還能產生卷動(scroll)的效果,下面例子展示了如何將一個列表向上卷動半頁。

scrollView = poco(type='ScollView')
scrollView.focus([0.5, 0.8]).drag_to(scrollView.focus([0.5, 0.2]))
  • UI等待
    在給定時間內等待一個UI出現并返回這個UI,如果已經存在畫面中了那就直接返回這個UI。 如果超時了還沒有出現,同樣也會返回,但是調用這個UI的操作時會報錯。(我真被這里坑死了)
poco('bg_mission').wait(5).click()  # wait 5 seconds at most,click once the object appears
poco('bg_mission').wait(5).exists()  # wait 5 seconds at most,return Exists or Not Exists
  • 截圖 snapshot
    截屏幕并以base64編碼返回。截圖的格式(png, jpg, …)由對應的sdk實現決定,大多數情況下是png。
from base64 import b64decode

b64img, fmt = poco.snapshot(width=720)
open('screen.{}'.format(fmt), 'wb').write(b64decode(b64img))
  • 全局操作
    在沒有選定或指定UI的情況下也可以進行操作(模擬輸入),也叫全局操作。
poco.click([0.5, 0.5])  # click the center of screen
poco.long_click([0.5, 0.5], duration=3)

# swipe from A to B
point_a = [0.1, 0.1]
center = [0.5, 0.5]
poco.swipe(point_a, center)

# swipe from A by given direction
direction = [0.1, 0]
poco.swipe(point_a, direction=direction)

常見異常

from poco.exceptions import PocoTargetTimeout
from poco.exceptions import PocoNoSuchNodeException


使用命令行運行腳本

官方文檔: http://airtest.netease.com/docs/docs_AirtestIDE-zh_CN/4_run_script/run_script.html#id3

運行腳本

PS E:\treasure\Airtest> [python -m] airtest run parkIndex.air --log E:/CatJmx/ParkTest/Airtest/log

可選參數:

  • [--recording]

讓airtest自動對腳本執行過程中的手機屏幕進行錄制操作。錄制完成后,將自動生成一個命令格式類似于 recording_0.mp4 的文件到腳本生成的log目錄中。在最后生成報告時,這個mp4文件會默認顯示在HTML報告頁面里。

  • [--device]

設備字符串,什么都不填寫,會默認取當前連接中的第一臺手機;字串完整定義格式:Android://<adbhost[localhost]>:<adbport[5037]>/<serialno>

  • [--log]

指定生成的log目錄路徑,默認為腳本所在目錄

生成報告

腳本運行過程,與報告生成過程是獨立的兩個步驟,因此在運行過 airtest run script.air后,假如沒有指定 --log log/ 參數,Airtest 將把生成的log內容放到當前命令行的執行目錄里(如果指定了 --log 參數,log內容與截圖將會放在指定目錄里)

PS E:\treasure\Airtest> [python -m] airtest report parkIndex.air --log_root E:/CatJmx/ParkTest/Airtest/log --outfile log/log.html --lang zh --export E:/CatJmx/ParkTest/Airtest --plugin poco.utils.airtest.report

可選參數:

  • [--log_root]
    日志根目錄,日志文件應該是 log_root / log.txt

  • [--outfile]
    指定輸出html文件路徑,默認為log.html

  • [--static_root]
    靜態文件根目錄

  • [--lang zh]
    設置報告語言

  • [--export]
    在使用 airtest report 指令生成的報告中,使用了絕對路徑來訪問里面的圖片文件,同時HTML報告中訪問的靜態css與js資源文件,也是硬盤上的絕對路徑(默認在airtest的安裝目錄下的report文件夾里)。因此,假如想要發送報告給其他人觀看,就必須要在命令行末尾加上 --export 導出目錄,將報告導出到一個指定目錄中,然后將整個目錄發送給別人查看;

  • [-plugin poco.utils.airtest.report]
    默認報告是airtest的專屬報告,對于poco語句的支持不夠完善,需要使用插件的形式來補充;

  • [--plugin airtest_selenium.report]

    如果腳本中使用了selenium插件,在生成報告的命令行最后,需要加入 --plugin airtest_selenium.report,可以讓報告支持selenium元素;

[To be continued...]

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容