Python Appium自動(dòng)化測(cè)試 獲取控件ID

Time will tell.

在前面的章節(jié)里,分享了通過獲取控件坐標(biāo)點(diǎn)來獲取點(diǎn)擊事件所需要的點(diǎn)擊位置届囚,那么還有其他獲取控件點(diǎn)擊事件所需要點(diǎn)擊位置的方法嗎颓影?當(dāng)然有。

在不同大小屏幕的手機(jī)上獲取控件的坐標(biāo)點(diǎn)妇穴,不是一樣的。因此在不同的機(jī)型上需要重新獲取坐標(biāo)點(diǎn)隶债。如果操作控件特別多腾它,那么獲取控件的坐標(biāo)點(diǎn)就會(huì)特別繁瑣。因此可以通過獲取控件 ID 來避免獲取控件坐標(biāo)點(diǎn)的這種弊端死讹。

控件 ID 的獲取主要通過HierarchyViewer瞒滴,下面從打開和使用兩方面進(jìn)行講解。

1赞警、HierarchyViewer 打開方式

HierarchyViewer的打開方式有兩種:

  • 一種是eclipse中打開HierarchyView視圖妓忍;

  • 第二種是命令行中執(zhí)行sdk/tools/hierarchyviewer.bat。

HierarchyViewer默認(rèn)只能在非加密設(shè)備使用愧旦,例如工程機(jī)世剖,工程平板或者模擬器。如果要在手機(jī)上使用HierarchyViewer笤虫,你需要在你的應(yīng)用中添加一個(gè)開源庫(kù)View Server旁瘫。鏈接地址:https://github.com/romainguy/ViewServer ,里面有講解如何啟動(dòng)真機(jī)View Server琼蚯。

方式一:

連接你的真機(jī)設(shè)備或打開模擬器酬凳,在 eclipse 中, 依次選擇 Window - Open Perspective - Other遭庶,在 Other 中宁仔,選擇HierarchyView視圖,即可打開罚拟。

方式二:

連接您的真機(jī)設(shè)備或打開模擬器台诗,運(yùn)行 cmd 窗口完箩,進(jìn)入到 sdk/tools 目錄下,輸入命令hierarchyviewer.bat拉队,運(yùn)行hierarchyviewer 弊知。

或直接在 sdk/tools 目錄下,找到hierarchyviewer.bat粱快,雙擊運(yùn)行秩彤。

未開啟夜神模擬器的HierarchyViewer

開啟夜神模擬器后的HierarchyViewer

2、HierarchyViewer 獲取控件 ID

HierarchyViewer啟動(dòng)后事哭,首先會(huì)看到的第一個(gè)窗口顯示了設(shè)備和模擬器的列表漫雷。點(diǎn)擊左邊的箭頭,就會(huì)展開當(dāng)前設(shè)備或模擬器的Activity對(duì)象列表鳍咱。列表中顯示了設(shè)備或模擬器上降盹, UI 當(dāng)前可視的所有Activity對(duì)象。

這些對(duì)象按照它們的 Android 組件名稱列出來谤辜。列表中的內(nèi)容包含應(yīng)用的Activity對(duì)象和系統(tǒng)的Activity對(duì)象蓄坏。

當(dāng)模擬器Activity畫面變更后,點(diǎn)擊refresh可以加載新的頁(yè)面布局信息丑念。

從列表中選擇你的 activity 名稱涡戳,雙擊,或點(diǎn)擊菜單欄的 Load View Hierarchy按鈕脯倚,進(jìn)入View Hierarchy窗口渔彰,查看它的view層次結(jié)構(gòu);或者點(diǎn)擊 Inspect Screenshot按鈕推正,進(jìn)入Pixel Perfect窗口恍涂,從而查看 UI 的一個(gè)放大圖像。我們這里點(diǎn)擊進(jìn)入View Hierarchy窗口舔稀。

從下圖中看到模擬器此 activity 的畫面布局信息乳丰,左邊部分是hierarchy通過樹形結(jié)構(gòu)展示的布局形式,右下角是模擬器上當(dāng)前頁(yè)面的 UI 布局信息内贮。

通過滾動(dòng)鼠標(biāo),可以放大每個(gè)樹節(jié)點(diǎn)汞斧。拖拽鼠標(biāo)夜郁,移動(dòng)樹形結(jié)構(gòu)布局。雙擊樹節(jié)點(diǎn)可以展示單獨(dú)的 UI 部分粘勒。從下圖中竞端,可以看到,id/btn_login即為登錄按鈕的 ID 庙睡。依次類推事富,可以查看其它控件 ID 技俐。

對(duì)于列表、或者彈出框則無法直接通過點(diǎn)擊 ID 操作成功统台,需要計(jì)算 ID 的坐標(biāo)雕擂。

3、控件 ID 之 Monkeyrunner 腳本演示

同樣贱勃,我們將下面一段 Monkeyrunner 腳本寫到一個(gè)test.py文件中井赌,然后運(yùn)行test.py文件,查看模擬器上是不是做相應(yīng)的操作贵扰。

# coding=utf-8
# 1.先設(shè)置編碼仇穗,utf-8可支持中英文,如上戚绕,一般放在第一行
# 2.注釋:包括記錄創(chuàng)建時(shí)間纹坐,創(chuàng)建人,項(xiàng)目名稱舞丛。
# 3.導(dǎo)入模塊

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice
from com.android.monkeyrunner.easy import EasyMonkeyDevice #提供了根據(jù)ID進(jìn)行訪問
from com.android.monkeyrunner.easy import By #根據(jù)ID返回PyObject的方法

device=MonkeyRunner.waitForConnection()

#啟動(dòng)activity(這里啟動(dòng)qq)

device.startActivity(component="com.tencent.mobileqq/.activity.SplashActivity")

easy_device=EasyMonkeyDevice(device) #必須在activity啟動(dòng)之后

#登錄界面耘子,點(diǎn)擊賬號(hào)輸入框

easy_device.touch(By.id('id/0x20e'),MonkeyDevice.DOWN_AND_UP)

device.type('721471592') #輸入qq賬號(hào)

至此,獲取控件ID的方式已經(jīng)介紹完瓷马,由于沒有深入研究拴还,肯定有不少功能點(diǎn)沒有介紹到,有時(shí)間的話再做完善欧聘。

4片林、控件 ID 不存在或重復(fù)

在用 monkeyrunner 進(jìn)行 Android 自動(dòng)化時(shí),通過獲取坐標(biāo)點(diǎn)或控件 ID 進(jìn)行一系列操作怀骤。由于使用坐標(biāo)點(diǎn)時(shí)费封,屏幕分辨率一旦更改,則代碼中用到坐標(biāo)的地方都要修改蒋伦,這樣導(dǎo)致代碼的復(fù)用率較低弓摘。因此,我們多采用控件 ID 操作痕届,注意控件 ID 需要在模擬器中使用韧献,對(duì)于絕大多數(shù)真機(jī)不適用。但是研叫,某些控件的 ID 是不存在的或重復(fù)存在锤窑,那么,遇到這種情況嚷炉,我們?cè)鯓永^續(xù)使用控件 ID 進(jìn)行自動(dòng)化測(cè)呢渊啰?

例如,下圖中,我想要獲取最右側(cè)紅框中的 id/tv 绘证,但是隧膏,大家會(huì)發(fā)現(xiàn),和它并列的也有重復(fù)的控件 id 值∪履牵現(xiàn)在我們就講述一下這種情況(控件 ID 不存在同樣處理)胞枕。

我們從這個(gè)控件樹的節(jié)點(diǎn)角度來思考如何獲得控件的引用。我們可以看到在上圖hierarchy viewer中的每個(gè)控件所對(duì)應(yīng)的框形中车酣,右下角都有一個(gè)數(shù)字曲稼。其實(shí)這個(gè)數(shù)字就是該控件在同級(jí)兄弟節(jié)點(diǎn)中的索引值,我們知道這個(gè)索引值后湖员,就可以根據(jù)parentView.children[index]屬性來獲取任意父節(jié)點(diǎn)所對(duì)應(yīng)的子節(jié)點(diǎn)的對(duì)象引用贫悄。其中的parentView可以是樹形圖中有效 ID 的任意父節(jié)點(diǎn)(父節(jié)點(diǎn)要保證唯一有效),然后利用python函數(shù)的可變參數(shù)列表特性來傳入所需控件的索引列表即可構(gòu)造出得到任意節(jié)點(diǎn)引用的字符串娘摔,從而得到其引用窄坦。

核心代碼如下,把如下代碼加入自己的 python 腳本中凳寺,直接調(diào)用該函數(shù)即可鸭津。

#定義獲取重復(fù)或不存在控件id,尋找子節(jié)點(diǎn)函數(shù)
def getChildView(parentId, *childSeq):
    hierarchyViewer = device.getHierarchyViewer()
    childView="hierarchyViewer.findViewById('" + parentId +"')"
    for index in childSeq:
        childView += ('.children[' + str(index) + ']')
    print childView
    return eval(childView) 

#獲取id的文本
def getText(view):  
    if view != None:           
       return (view.namedProperties.get('text:mText').value)

有了以上代碼之后肠缨,我們可以獲取上圖中的 id/tv 逆趋,方法如下:

getChildView('id/province_list',5,0,0)

其中結(jié)合上圖可知,getChildView的第一個(gè)參數(shù)即:有效且唯一的父節(jié)點(diǎn)

參數(shù)二晒奕、三依次為要獲取的控件 ID 的父節(jié)點(diǎn)的父節(jié)點(diǎn)

注:用到的父節(jié)點(diǎn)即圖中的id/province_list闻书,有效且唯一的值。當(dāng)前的父節(jié)點(diǎn)右下角的角標(biāo)脑慧,不需要在getChildView函數(shù)中顯示魄眉。

這樣,通過以上函數(shù)闷袒,再結(jié)合Hierarchyviewer圖形坑律,我們獲取到了重復(fù)的控件ID。

由于Hierarchyviewer看起來不是特別方便囊骤,這里再推薦一款和Hierarchyviewer類似功能的工具:uiautomatorviewer(存儲(chǔ)在sdk\tools中晃择,雙擊打開即可)。

由上圖中也物,uiautomatorviewer每個(gè)控件前面的數(shù)字即相當(dāng)于Hierarchyviewer的角標(biāo)藕各,我們同樣可以獲取到目標(biāo) ID 的最終有效且唯一的父節(jié)點(diǎn),從而調(diào)用函數(shù)getChildView('id/province_list',5,0,0)

獲取到了不存在或重復(fù)的控件 ID 后焦除,我們可以通過其坐標(biāo),進(jìn)行點(diǎn)擊操作作彤。

首先膘魄,定義一個(gè) “獲取指定按鈕坐標(biāo)” 的函數(shù)

def getBtnPoint(btn):
    print btn
    point = device.getHierarchyViewer().getAbsoluteCenterOfView(btn);
    return point

然后我們可以通過坐標(biāo)乌逐,實(shí)現(xiàn)點(diǎn)擊操作,例如:

askView = getChildView('id/tabs',1)
askPpoint = getBtnPoint(askView)
device.touch(askPpoint.x,askPpoint.y,'DOWN_AND_UP')

至此创葡,我們介紹完了處理控件 ID 不存在或重復(fù)時(shí)的方法浙踢,有興趣的小伙伴或者童鞋們可以自己動(dòng)手實(shí)踐一把,就會(huì)更能體會(huì)Hierarchyviewer/uiautomatorviewer + getChildView()獲取不存在或重復(fù)控件 ID 的用法灿渴、樂趣及其奧秘洛波。

大概意思是說,單獨(dú)版本的hieararchyviewer已經(jīng)被棄用了骚露。請(qǐng)使用 Android Device Monitor 來代替蹬挤。Android Device Monitor 在 tools 目錄下面找到monitor.bat即可。

為了緊跟時(shí)代潮流棘幸,就決定用 Android Device Monitor 啟動(dòng)即可焰扳。

具體操作啟動(dòng)步驟:

1、運(yùn)行命令monitor.bat误续,如下:

2吨悍、運(yùn)行命令后出現(xiàn),如下:

3蹋嵌、點(diǎn)擊 “Window->Open Perspective” 育瓜。如圖:

4、按第三步操作完以后栽烂,出現(xiàn)如下:

5躏仇、選擇“hieararchyviewer ”,點(diǎn)擊“OK” 即可愕鼓,如下:


如何在真機(jī)上正常使用Hierarchy View

Hierarchy Viewer如果不進(jìn)行 “特殊” 配置的話是無法連接真機(jī)钙态,會(huì)報(bào)以下錯(cuò)誤:

[hierarchyviewer]Unable to get view server version from device XXXXX

[hierarchyviewer]Unable to get view server protocol version from device XXXXXX

[ViewServerDevice]Unable to debug device: XXXXX

[hierarchyviewer]Missing forwarded port for XXXXX

[hierarchyviewer]Unable to get the focused window from device XXXXX

無法連接真機(jī)的原因是:To preserve security, Hierarchy Viewer can only connect to devices running a developer version of the Android system.

出于安全性考慮, Hierarchy Viewe 只能連接開發(fā)版手機(jī)或模擬器菇晃。

Android 源碼實(shí)現(xiàn)這一限制的地方在 /frameworks/base/services/core/java/com/android/server/wm/WindowManageService.java :

檢驗(yàn)一臺(tái)手機(jī)/模擬器是否開啟了View Server的辦法是:

adb shell service call window 3

若返回值是:Result: Parcel(00000000 00000000 '........')" 說明View Server處于關(guān)閉狀態(tài)

若返回值是:Result: Parcel(00000000 00000001 '........')" 說明View Server處于開啟狀態(tài)

有時(shí)碰到模擬器或開發(fā)發(fā)版手機(jī)册倒,view Hierarchy 還是無法連接,可以先使用以上方法檢查一下View Server狀態(tài)磺送。如果沒有開啟驻子,則使用以下命令打開View Server

adb shell service call window 1 i32 4939

也可以使用使用以下命令關(guān)閉View Server:

adb shell service call window 2 i32 4939

那么如何在真機(jī)能夠正常使用Hierarchy Viewer呢?這里總結(jié)了以下幾個(gè)方法:

方法一:

配置設(shè)備估灿,打開手機(jī)的開發(fā)者選項(xiàng)崇呵。

如果你的手機(jī)是 android 4.0 或者以下,請(qǐng)根據(jù)開源項(xiàng)目 View Server(https://github.com/romainguy/ViewServer) 進(jìn)行安裝和配置馅袁。

如果你的手機(jī)是4.1或以上域慷,則必須進(jìn)行以下環(huán)境變量配置:

  1. 點(diǎn)擊 計(jì)算機(jī)屬性-》高級(jí)系統(tǒng)設(shè)置-》環(huán)境變量

  2. 新建環(huán)境變量ANDROID_HVPROTO, 并設(shè)置其值為ddm,保存重啟

該方法參考 android 官方文檔《Device Setup for Hierachy Viewer》https://developer.android.com/studio/profile/hierarchy-viewer-setup.html

然而在親自試用真機(jī)(魅族MX4pro android 5.1 和 android 4.4的機(jī)頂盒)測(cè)試過程中犹褒,配置環(huán)境變量的方法似乎并沒有起到作用抵窒,還是連不上。

不過直接在調(diào)試 app 中集成 View Server 開源項(xiàng)目是沒有任何問題的叠骑。


方法二:

話說前面Hierarchy Viewer只能連接 Android 開發(fā)版手機(jī)或是模擬器李皇,只有ro.secure==0 && ro.debuggable==1 的 Android 系統(tǒng)。ro.xxxx這種句式是不是覺得有點(diǎn)熟悉宙枷?不就是 android 系統(tǒng)的/system/build.prop文件中的配置樣式么掉房。推測(cè)如果將ro.secure==0 && ro.debuggable==1這個(gè)兩個(gè)配置添加進(jìn)來應(yīng)該能夠起作用吧,于是進(jìn)行以下嘗試:

  1. 先把手機(jī)root

  2. 在進(jìn)到在/system/build.prop中添加ro.secure==0ro.debuggable==1慰丛, 保存配置并重啟手機(jī)卓囚,Hierarchy Viewer連接正常,終于可以正常調(diào)試了璧帝。


好了捍岳,關(guān)于控件ID的獲取就分享到這里。希望大家都能熟練掌握睬隶。如果你對(duì)Python自動(dòng)化軟件測(cè)試感興趣可以加入我們扣裙一起學(xué)習(xí)175317069锣夹。有各項(xiàng)測(cè)試學(xué)習(xí)資源,也有行業(yè)深潛多年的技術(shù)人分析講解苏潜。

歡迎【點(diǎn)贊】银萍、【評(píng)論】、【關(guān)注】~

Time will tell.(時(shí)間會(huì)證明一切)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末恤左,一起剝皮案震驚了整個(gè)濱河市贴唇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌飞袋,老刑警劉巖戳气,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異巧鸭,居然都是意外死亡瓶您,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門纲仍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呀袱,“玉大人,你說我怎么就攤上這事郑叠∫拐裕” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵乡革,是天一觀的道長(zhǎng)寇僧。 經(jīng)常有香客問我摊腋,道長(zhǎng),這世上最難降的妖魔是什么婉宰? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任歌豺,我火速辦了婚禮,結(jié)果婚禮上心包,老公的妹妹穿的比我還像新娘。我一直安慰自己馒铃,他們只是感情好蟹腾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著区宇,像睡著了一般娃殖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上议谷,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天炉爆,我揣著相機(jī)與錄音,去河邊找鬼卧晓。 笑死芬首,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逼裆。 我是一名探鬼主播郁稍,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼胜宇!你這毒婦竟也來了耀怜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤桐愉,失蹤者是張志新(化名)和其女友劉穎财破,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體从诲,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡左痢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盏求。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抖锥。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖碎罚,靈堂內(nèi)的尸體忽然破棺而出磅废,到底是詐尸還是另有隱情,我是刑警寧澤荆烈,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布拯勉,位于F島的核電站竟趾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宫峦。R本人自食惡果不足惜岔帽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望导绷。 院中可真熱鬧犀勒,春花似錦、人聲如沸妥曲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)檐盟。三九已至褂萧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間葵萎,已是汗流浹背导犹。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留羡忘,地道東北人谎痢。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像壳坪,于是被迫代替她去往敵國(guó)和親舶得。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容