poco節點關係大公開!

AirtestProject發表於2024-04-18

此文章來源於專案官方公眾號:“AirtestProject”
版權宣告:允許轉載,但轉載必須保留原連結;請勿用作商業或者非法用途

一、前言

在自動化測試的實踐中,我們發現許多同學在使用Poco框架進行控制元件定位時,對於節點之間的關係理解不夠深入。那麼本週讓我們來詳細講解Poco框架中的child&childrenoffspringsiblingparent等節點關係定位方法。

二、Poco定位節點的關係分析

2.1 child&children

從字面上看,可以很明顯知道childchildren表示的就是獲取該節點下的子節點。如果是需要獲取多個子節點,需要透過for去迴圈提取,不透過迴圈獲取的話,預設都是提取第一個節點,但順序編號從0開始。

其中child可以攜帶引數,可以獲取指定的子節點,如:

poco("android.widget.FrameLayout").child("android.widget.LinearLayout")

children是不能攜帶引數的,是可以直接獲取所有的子節點,但可以根據返回的子節點順序進行指定,預設返回的是提取的第一個節點(順序編號從0開始)如:

poco("android.widget.FrameLayout").children()[2]

2.2 offspring

offspring是獲取該節點的子孫節點,若需要輸出多個子孫節點,使用for迴圈去進行輸出,預設輸出為首個子孫節點。在使用過程中,如果不清楚自己所需節點的編號為多少,我們可以選擇用for輸出後,按照順序編號進行選擇使用。

poco("com.netease.cloudmusic:id/bannerContainer").offspring()

可以根據輸出的順序,結合下圖,其中下述語句表達為“每日推薦”控制元件:

poco("com.netease.cloudmusic:id/portal_rv").offspring()[10]

也可以在offspring括號內指定自己所需要的子孫節點,如:

poco("com.netease.cloudmusic:id/portal_rv").offspring("com.netease.cloudmusic:id/portalTitle")

上述語句同樣表示為“每日推薦”控制元件。這樣有個好處就是,當有多個相同name的控制元件但存在不同name的上層節點時,可以很好的區分每個控制元件。

2.3 sibling

siblings表示獲取當前節點的兄弟節點,即與當前節點處於同一層級的其他節點。若需要輸出多個兄弟節點,使用for迴圈進行輸出,預設輸出為首個兄弟節點。

poco("com.netease.cloudmusic:id/biFl").sibling()

如下圖,可以看到該節點下返回的兄弟節點與UI樹相匹配:

同樣,sibling也是可以根據迴圈獲取輸出的順序進行指定的,如:

poco("com.netease.cloudmusic:id/biFl").sibling()[3]

2.4 parent

在poco中,parent表示獲取當前節點的父節點。如果需要獲取整個節點集合的父節點,需要找到節點集合的第一個節點。 如果需要獲取多層父節點,可以透過.parent()方法進行逐級獲取。

例如,對於一個節點A,它的父節點是B,B的父節點是C,那麼可以透過A.parent().parent()來獲取到節點C。

poco("com.android.systemui:id/status_bar_contents").parent()

綜上所述,如果需要獲取該介面的所有節點,可以透過.parent().children() 等方法互相結合來獲取其他層級中的所有節點,然後再透過遍歷篩選出除了當前節點外的其他節點。
在開源群內,有一些同學也問過如何統計UI樹某層或某控制元件的個數,我們可以透過上述的節點關係,結合python已有的len()函式,或使用for迴圈累加的方式去獲取的。如:

#【利用子孫節點關係定位元素】統計輸出熱歌榜當前介面中歌曲數量
num=len(poco("com.netease.cloudmusic:id/musicInfoList").offspring(nameMatches="com.*?songName"))    
print("當前介面有{}首歌".format(num))

#【利用子節點關係定位元素】統計輸出當前介面的熱門節目單數量
num=0
for x in poco("CollectionView").child("UIA.Podcasts.ShelfItem.show"):
    print(x.child().child().get_name())
    num+=1

三、Android上的案例

瞭解完Poco節點關係的具體用法後,我們可以嘗試在日常跑測中使用上節點關係,讓我們來看一下在Android上的一個使用案例吧。

參考程式碼如下:

可以看到,我們透過節點關係可以獲取到它的父節點、兄弟節點、子孫節點等,並可以對其進行點選、統計、輸出資訊等操作。

# -*- encoding=utf8 -*-
__author__ = "Airtest"

from airtest.core.api import *

auto_setup(__file__)

from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

#開啟網易雲音樂
start_app("com.netease.cloudmusic")
sleep(7.0)

#【利用子孫節點關係尋找元素】透過輸出子孫節點去查詢“發現”按鈕
for i in poco("com.netease.cloudmusic:id/bottomNav").offspring(nameMatches="com.*?desc"):
    print(i.get_text())

#【利用子孫節點關係以及空間順序定位元素】點選"發現"按鈕
poco("com.netease.cloudmusic:id/bottomNav").offspring(nameMatches="com.*?desc")[1].click()
sleep(1.0)

#【透過兄弟節點關係定位元素】點選發現頁中“精選”旁邊的“排行榜”按鍵
poco("精選").sibling()[1].click()
sleep(1.0)

#點選熱歌榜
poco(text="熱歌榜").click()

#【利用子孫節點關係尋找元素】輸出熱歌榜中每首歌的名字
print("當前介面的熱歌榜歌曲有:")
for i in poco("com.netease.cloudmusic:id/musicInfoList").offspring(nameMatches="com.*?songName"):
    print(i.get_text())
    
#【利用子孫節點關係定位元素】統計輸出熱歌榜當前介面中歌曲數量
num=len(poco("com.netease.cloudmusic:id/musicInfoList").offspring(nameMatches="com.*?songName"))    
print("當前介面有{}首歌".format(num))
    
#【利用子節點關係定位元素】輸出目前播放器在播放的歌曲名
print("下方為正在播放的歌曲:")    
now_song = poco("com.netease.cloudmusic:id/minibar_song_container").child().children()   
print(now_song.get_text())

四、iOS上的案例

日常使用中可以發現,在iOS上獲取對應的UI樹控制元件比較困難,但是可以透過Poco節點關係的方法,更大程度地去尋找到自己想要獲取的控制元件或ui樹節點。

參考程式碼如下:

# -*- encoding=utf8 -*-
__author__ = "Airtest"

from airtest.core.api import *

auto_setup(__file__)
from poco.drivers.ios import iosPoco
poco = iosPoco()

#開啟播客app
poco("播客").click()

#【利用子節點關係定位元素】輸出該介面的資訊,點選選擇檢視熱門節目
for i in poco("CollectionView").child():
    print(i.get_name())

#【利用子節點關係結合子孫節點關係定位元素】點選進入熱門節目介面 
poco("CollectionView").child("熱門節目").offspring("檢視全部").click()

#【利用子節點關係定位元素】輸出當前介面的熱門節目單
num=0
print("當前熱門節目單有:")
for x in poco("CollectionView").child("UIA.Podcasts.ShelfItem.show"):
    print(x.child().child().get_name())
    num+=1

#【透過迴圈累計獲取節點個數】輸出當前介面的熱門節目數量
print("當前介面有{}個節目".format(num))   

#【利用父節點關係結合子節點關係定位元素】點選播放鍵進入播放介面
poco("MiniPlayerArtworkVisible").parent().child()[2].child()[0].click()

#【利用兄弟節點關係定位元素】點選播放鍵進行播放
poco("倒回,15秒鐘").sibling()[1].click()

五、小結

本週我們介紹了Poco節點關係:

1、child&children 獲取子節點

2、offspring 獲取子孫節點

3、sibling 獲取兄弟節點

4、parent 獲取父節點

透過深入理解child&childrenoffspringsiblingparent這些節點關係,我們能夠更加精確和高效地定位到UI樹中的各個節點。

如果同學們在使用Poco進行自動化測試的過程中,遇到了問題,或者有任何想要深入瞭解的知識點,歡迎在群裡告訴我們或者提交issue,也歡迎大家投稿。後續我們會帶來更多精彩的有關Poco專題內容,請大家持續關注我們,敬請期待哦!


AirtestIDE下載:airtest.netease.com/
Airtest 教程官網:airtest.doc.io.netease.com/
搭建企業私有云服務:airlab.163.com/b2b

官方答疑 Q 群:526033840

相關文章