Airtest (poco 框架) 元素定位實戰
對於 UI 自動化測試來說,處理好元素定位問題對於提高測試設計效率顯得尤為重要,本文以美團 APP 選擇商品頁面為例,介紹在使用 Airtest(Poco 框架)進行元素定位時可能遇到的問題以及相應的處理方式。
目標頁面如下所示:
假設頁面上的藥品是我們的測試資料,現在需要點選 “+” 圖示,新增指定藥品到購物車。
透過 Airtest IDE 檢視 “+” 圖示元素屬性:
Path from root node: [0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 4, 0, 0]
Payload details:
type : android.widget.ImageView
name : com.sankuai.meituan:id/img_foodCount_add_fix
enabled : True
visible : True
resourceId : b'com.sankuai.meituan:id/img_foodCount_add_fix'
zOrders : {'global': 0, 'local': 1}
package : b'com.sankuai.meituan'
anchorPoint : [0.5, 0.5]
dismissable : False
checkable : False
scale : [1, 1]
boundsInParent : [0.10277777777777777, 0.04625]
focusable : False
touchable : True
longClickable : False
size : [0.10277777777777777, 0.04625]
pos : [0.5259259259259259, 0.37583333333333335]
focused : False
checked : False
editalbe : False
selected : False
scrollable : False
很明顯,我們可以透過 name 屬性獲得頁面上所有的 “+” 號圖示構成列表,然後根據索引選擇需要點選的目標,但是這種做法存在不足,隨著測試資料的變化、頁面佈局的變化,我們不知道自己點的是哪件商品,當然也會影響到後續對於測試資料的校驗。
所以,現在新的需求是新增指定的商品到購物車,下文以 “[精華] 正柴胡飲顆粒 5g*10 袋” 這件商品為例。
首先,我們得知道 Poco 框架支援透過 text 屬性精確找到元素,程式碼如下:
item_text_obj = poco(text="[精華]正柴胡飲顆粒5g*10袋") # 找到待測商品名稱對應的元素
找到的元素在 Airtest UI 樹中展示如下:
同時,可以找到待點選的 “+” 號圖示在 UI 樹中所處的位置:
透過觀察 UI 樹,可以得出目標元素(target_obj)與商品文字元素 (item_text_obj) 之間的對應關係:
商品文字元素的父節點的第五個子節點的第一個子節點的子節點就是我們要點選的目標元素。
對應的完整 Poco 程式碼如下:
item_text_obj = poco(text="[精華]正柴胡飲顆粒5g*10袋") # 找到待測商品名稱對應的元素
foo_parent = item_text_obj.parent()
foo_childs = foo_parent.child()
target_obj = foo_childs[4].child()[0].child()[0]
target_obj.click()
這段程式碼放到 Airtest 執行可以透過,但是很遺憾,並不會點選到加號目標,而是進入到商品詳情頁面。
透過列印 target_obj 屬性便可發現問題出在哪裡:
日誌顯示,根據總結的規律找到的元素 name 是 “com.sankuai.meituan:id/txt_stickyfoodList_adapter_food_price_fix”,而之前我們已經知道期望點選的元素 name 是 “com.sankuai.meituan:id/img_foodCount_add_fix”,回到 Airtest 中的 UI 樹,不難找到實際點選的元素位置:
這裡其實揭示了 Poco 框架一個令人相當不爽的問題,對於任一元素的子元素,我們並不能很輕易地確定其正確的索引。
甚至存在這種可能,對於 A 商品,目標元素索引是 1,換成 B 商品,索引有可能又變成 0 了,有興趣的可以自己慢慢嘗試。
# 索引錯誤會導致找不到元素或點錯元素
# target_obj = foo_childs[4].child()[0].child()[0]
target_obj = foo_childs[4].child()[1].child()[0] # 這才是正確的索引
target_obj.click()
問題已經找到,最後說說解法。
解法一:
item_text_obj = poco(text="[精華]正柴胡飲顆粒5g*10袋") # 找到待測商品名稱對應的元素
foo_parent = item_text_obj.parent()
target_obj = foo_parent.offspring('com.sankuai.meituan:id/img_foodCount_add_fix')
Poco 找子元素除了 child 方法還有 offspring 方法,支援找到指定 name 的後代元素(注意與子元素的區別),如果目標元素的 name 可以唯一確定元素,建議使用這種方式處理。
解法二:
def get_child_by_index(element_p, structure, index):
"""
根據可見的元素位置關係選擇子元素
:param element_p: 父節點
:param structure: l表示元素佈局為左右結構,v表示上下結構,
:param index: 序號,按從左往右,從上往下順序取
:return:
"""
temp_list = []
element_list = []
for element_c in element_p.child(): # 遍歷子節點
temp_list.append({'element': element_c, 'pos': element_c.attr('pos')}) # 將元素以及其位置POS屬性構造成字典以後再存入列表
if structure == 'l': # 左右結構
temp_list.sort(key=lambda e: e['pos'][0], reverse=False) # 呼叫列表sort排序方法,排序的key是字典的POS鍵值的下標為0的值,即橫座標
elif structure == 'v': # 上下結構
temp_list.sort(key=lambda e: e['pos'][1], reverse=False) # 呼叫列表sort排序方法,排序的key是字典的POS鍵值的下標為1的值,即縱座標
for element in temp_list:
element_list.append(element['element'])
return element_list[index]
item_text_obj = poco(text="[精華]正柴胡飲顆粒5g*10袋") # 找到待測商品名稱對應的元素
foo_parent = item_text_obj.parent()
foo1 = get_child_by_index(foo_parent, 'v',4) # 從上往下分別是圖片,名稱,銷售額等資訊
foo2 = get_child_by_index(foo1, 'l', 1) # 從左往右分別是價格資訊、加號按鈕
target_obj= foo2.child()
target_obj.click()
解法二的思路已經寫在註釋裡了,全文完。
相關文章
- Selenium實戰教程系列(二)—元素定位
- Selenium實戰教程系列(二)---元素定位
- 請教下,appium 中用了些 airtest 影像定位,導致 appium 定位失敗找不到元素APPAI
- Web自動化必會知識:「Web基礎、元素定位、元素操作、Selenium執行原理、專案實戰+框架」Web框架
- Selenium實現元素定位
- Playwright自動化測試工具之元素定位實戰
- Poco框架實操:對節點可實施的操作框架
- 元素定位
- appium元素定位APP
- Poco 框架實操:獲取節點屬性的高效技巧 (一)框架
- Poco框架實操:獲取節點屬性的高效技巧(一)框架
- selenium常用元素定位方式
- Selenium Web元素定位方法Web
- Selenium系列4-元素定位
- ios XCUIElement 元素定位問題iOSUI
- Cypress 基礎 - 元素的定位
- html元素滾動定位方法HTML
- 如何選擇元素定位方式
- Python Selenium如何定位元素Python
- python_selenium元素定位_xpath(2)Python
- bs4元素定位
- position:fixed 相對父元素定位
- React.js 實戰之 元素渲染ReactJS
- Selenium4自動化測試4--元素定位By.XPATH,元素定位最佳順序
- 騰訊出品小程式自動化測試框架【Minium】系列(三)元素定位詳解框架
- Solidity的Truffle框架實戰Solid框架
- Selenium3自動化測試【17】元素定位之Link定位
- CSS遮罩/定位下面元素不能觸發CSS遮罩
- APPIUM-Android自動化元素定位方式APPAndroid
- absolute定位css元素居中的兩種方法CSS
- transform改變定位元素的包含塊ORM
- selenium-配置檔案定位元素(九)
- JavaScript陣列指定位置插入新元素JavaScript陣列
- Selenium系列教程- 04常用的元素定位方法
- 實戰分享反爬機制快速定位與破解
- Kafka實戰(三) - Kafka的自我修養與定位Kafka
- swoole 框架 swoft2.0 實戰框架
- position:sticky定位元素是否在同一父元素中區別