Appium+python自動化(十)- 元素定位祕籍助你打通任督二脈 - 上卷(超詳解)
簡介
你有道靈光從天靈蓋噴出來你知道嗎,年紀輕輕就有一身橫練的筋骨,簡直百年一見的練武奇才啊,如果有一天讓你打通任督二脈,那還不飛龍上天啊。正所謂我不入地獄誰入地獄,警惡懲奸維護世界和平這個任務就交個你了,好嗎。這本如來神掌祕籍是無價之寶,我看與你有緣,收你十塊錢傳授給你吧。想必這段經典臺詞給為都可以的耳熟能詳吧,巨集哥,沒這麼牛叉呼啦帶閃電,就是希望對你有幫助就可以了。
上一篇巨集哥給小夥伴們介紹完定位工具這兩個異性兄弟,這篇就給小夥伴們介紹一下定位方法。早就有小夥伴問,這個這個怎麼定位,那個那個怎麼定位?那麼巨集哥今天就告訴你,怎麼怎麼定位。其實定位前邊也有所涉及,只不過是一筆帶過的。這篇巨集哥就給小夥伴們詳細的介紹一下。
1、 常用定位方法講解
物件定位是自動化測試中很關鍵的一步,也可以說是最關鍵的一步,畢竟你物件都沒定位那麼你想操作也不行。所以本章節的知識巨集哥希望小夥伴們多動手去操作和實戰,不要僅僅只是書本上的知識,畢竟這個我只能夠舉例說明。下面我們來看我們常用的一些定位方式。
1.1 ID定位
無論是在web自動化還是app自動化中id都是唯一的,可能有的小夥伴看到這裡會有疑問,因為有的資料說是通過name定位是唯一的,為什麼你這裡是id呢,其實這個在之前是不衝突的,但是如果你用的是appium較新版本是不行的,在新版本中name定位被去掉了,所以在以後的定位中不會有name定位了,通常情況下我們也更喜歡用id進行定位。這裡可能剛學的小夥伴會有疑問,有的時候你的應用為什麼沒有id,或者說在這個手機上有但是另外的手機上沒有。1、開發沒有新增。2、android版本是4.4以下的。
我們直接看下面這張圖片吧
上面圖片中左邊部分用紅色圈出來的物件的id我們在右邊的屬性中可以看到,它的id巨集哥同樣是用紅色圈出,如果我們需要對“請輸入淘寶賬戶”這個輸入框進行輸入資訊,我們只需操作右邊的id就行,下面我們直接看程式碼。
1 driver.find_element_by_id("com.taobao.taobao:id/aliuser_login_account_et").send_keys("北京巨集哥")
通過上面的程式碼我們能夠直接在賬戶資訊輸入框中輸入賬戶資訊北京巨集哥。可能對於無基礎的人來說這裡會又點兒迷糊,這個driver是哪裡來的,driver在我們配置啟動的時就已經初始化,我們只需要呼叫他的方法find_element_by_id。如果你的ide有自動補全功能,那麼你在輸入後面的方法時會發現一個問題,為什麼還有一個find_elements_by_id呢?這個在後面巨集哥會講解,有興趣的小夥伴可以思考一下。
1.2 className定位
在實際工作中className定位用得相對而言會比較少。當你經常去看class時你會發現很多的className是一樣的,你沒有辦法對其進行唯一定位,下面我們看下面兩張圖片
我們可以仔細看一下這兩張圖片中淘寶賬號、密碼兩個輸入框中的className都是一樣的,如果在這種情況下你使用下邊這種方式去定位,你會發現你永遠定位不了密碼欄,這是為什麼呢?因為在設計的時候如果你查詢的元素在頁面有多個,系統會自動給你選擇第一個,所以你永遠操作不了後面的,那麼在實際工作或者實戰的時候如果遇到此類問題如何解決這種問題呢?巨集哥後面會講解。
driver.find_element_by_class_name("android.widget.EditText").send_keys("北京巨集哥")
1.3 xpath定位
xpath定位在web自動化中是最常見的,而且也是最有效的,使用xpath定位避免了找不到元素導致報錯的問題,但是在app中使用xpath定位是一件很low的事情。為什麼這麼說呢?因為在巨集哥過來人的經歷中只要遇見使用xpath定位元素他的反應就會比較慢,自動化的目的是為了提高效率,但是使用xpath後會降低效率,所以這裡說很 low。但很多時候我們不得不去了解,下面我們大概講解一下。首先我們要熟悉一下web的xpath定位。
1)講web的xpath之前大家先裝一下fireFox瀏覽器,再在瀏覽器中安裝fireBug以及FirePath兩個外掛。如下圖:
在自動化或者學習xpath時這兩個外掛是必不可少的,這裡我們直接講xpath,我們來看下面一張圖片理解一下
用紅色圈出有虛線的輸入框我們看一下xFirePath給我們的定位,在定位的xpath中顯示的是“.//*[@id='kw']”,這個是什麼意思呢?我們來一步一步講解。1、//* 選取文件中的所有元素 。2、@id='kw'] 匹配屬性為id且值為kw的節點。這裡有的小夥伴可能不是很理解,說這裡直接使用id進行定位就行。其實也是,但是當沒有這個屬性的時候呢?我們看下面這張圖片
name定位無效的情況下,當你看到這張圖片的時候如果你不用xpath怎麼定位呢?有一些抓狂的感覺吧。小夥伴可以嘗試著自己使用xpath進行定位,可能有一些人發現xpath中定位不是很明白了,為什麼呢?.//*[@id='u1']/a[4] 在這個xpath中我們沒有像之前那樣思路清晰了他多了一些層級關係,這個後面我們會仔細講。這個xpath中首先第一步1、@id='u1'和之前的一樣匹配屬性為id值為ul的節點,然後再在他的下面進行定位第二步2、/a[4] 意思就是從根節點下選取第四個a元素。這樣一步一步解析是否更加容易理解了呢?下面我們看一下在xpath定位中經常用到的一些語法,下來大家多多練習。
這個是我們經常用到的,而且是最基礎的知識,只有這些沒有辦法完成很多古怪的需求,那麼就有更難的,下面我們看下面的列表
上面這些知識都是在http://www.w3school.com.cn/xpath/xpath_examples.asp 裡面,大家可以多看看,多練習。
下面我們直接看在app中xpath的使用
在上面兩張圖片中我們能夠清除的看見他們的id、className都是一樣的,這樣的情況下不用層級定位方式我們只能夠採用xpath來進行定位,首先根據前面web的學習大家可以思考一下該怎麼定位。我們直接看程式碼
1 driver.find_element_by_xpath("//android.widget.TextView[@text='聚划算']").click()
在xpath裡面我們的語法是這樣“//android.widget.TextView[@text='JavaScript']”,這個和我們之前web的xpath一樣,意思是查詢所有節點中節點為android.widget.TextView (這裡使用的是className,也可以使用id,系統會依次去找)並且他的text屬性值為JavaScript,這樣是否更容易理解呢?下來多練習。這樣的定位方式不推薦,效率很慢。
2 、層級定位
2.1 什麼是層級定位
在前面的章節中我們已經提到了層級定位,只是不知道具體怎麼操作而已。在很多的自動化中如果只是靠簡單的定位是沒有辦法完成自動化的,就像剛xpath定位一樣,有的元素的id、name、className都是一樣的,xpath定位效率低下,這個時候我們大多數都會採用層級定位。
2.2 專案中層級定位如何運用
下面我們舉一個簡單的例子來理解層級定位。
從上面的圖片我們可以看出id為com.taobao.taobao:id/rv_main_container的節點下面包含了很多的android.widget.FrameLayout
從下面的圖片我們可以看出id為android.widget.FrameLayout的節點下面包含了很多的android.widget.LinearLayout
從這張圖片我們不難看出,如果我們要定位這個元素我們是沒辦法去定位的,這種情況我們大多數使用的是層級定位以及xpath,這裡我們來看如何使用層級定位。
首先我們可以看出三幅圖的結構上的區別,第三幅圖的元素它是在第二幅圖裡面的,第二幅圖元素它是在第一幅圖裡面的,這裡我們稱第一幅圖id(com.taobao.taobao:id/rv_main_container)為android.widget.FrameLayout的節點為第二幅圖元素的父節點,第二幅圖id(android.widget.FrameLayout)為android.widget.FrameLayout的節點為第三幅圖元素的父節點,第一幅圖id(com.taobao.taobao:id/rv_main_container)為android.widget.LinearLayout的節點為第三幅圖元素的祖父節點;我們只需要先通過id定位到祖父節點,然後再從祖父節點往下面依次進行定位就好。現在你可以練習一下,看和我的結果一樣嗎?看程式碼:
1 element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container") 2 element1 = element.driver.find_elements_by_class_name("android.widget.FrameLayout") 3 element2 = element1[1].find_element_by_class_name("android.widget.LinearLayout") 4 element2.click()
按照思維我們的程式碼會是上面的結果,但是你去執行會發現不報錯,可也不會點選,這個是為什麼呢?我們看下面的圖片(巨集哥親測,它會點選第一個天貓,可能是預設點選第一個吧)
在祖父節點下的所有子節點他的className都是“android.widget.FrameLayout”,在父節點下的所有子節點他的className都是“android.widget.LinearLayout”,這種情況下他怎麼去點選操作呢?所以在這種情況下會引發一個新的定位問題,就是巨集哥在接下來要講的List定位。
2.3參考程式碼
1 # coding=utf-8 2 # 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行 3 4 # 2.註釋:包括記錄建立時間,建立人,專案名稱。 5 ''' 6 Created on 2019-7-01 7 @author: 北京-巨集哥 QQ交流群:707699217 8 Project:學習和使用定位元素 9 ''' 10 # 3.匯入模組 11 from appium import webdriver 12 import time 13 desired_caps = {} 14 desired_caps['platformName'] = 'Android' #android的apk還是IOS的ipa 15 desired_caps['platformVersion'] = '8.0' #android系統的版本號 16 desired_caps['deviceName'] = '127.0.0.1:62001' #手機裝置名稱,通過adb devices 檢視 17 desired_caps['appPackage'] = 'com.taobao.taobao' #apk的包名 18 desired_caps['appActivity'] = 'com.taobao.tao.welcome.Welcome' #apk的launcherActivity 19 #desired_caps['unicodeKeyboard'] = True #使用unicodeKeyboard的編碼方式來發送字串 20 #desired_caps['resetKeyboard'] = True #將鍵盤給隱藏起來 21 driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) #啟動伺服器地址,後面跟的是手機資訊 22 # 休眠五秒等待頁面載入完成 23 time.sleep(5) 24 25 element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container") 26 element1 = element.find_elements_by_class_name("android.widget.FrameLayout") 27 element2 = element1[1].find_element_by_class_name("android.widget.LinearLayout") 28 element2.click() 29 30 # driver.quit()
小結
1、前邊介紹了一下火狐瀏覽器,這裡巨集哥再給小夥伴們總結一下谷歌瀏覽器如何用xpath定位,當然了,大神和大佬可以忽略不看,因為可以直接手寫xpath定位。其實看看他們的語法也很簡單,自己後期也可以嘗試手寫,看看和工具的有哪些區別,這樣可以有助於自己的提高和提升。
2、谷歌瀏覽器xpath外掛下載地址https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl
3、安裝方法,用谷歌瀏覽器直接訪問上邊的地址,新增以後即可。
4、看一下如何使用和其效果
(1)谷歌瀏覽器,F12,不可以的話,可以開啟“開發者工具”
(2)點選左邊的“箭頭”,查詢到要定位的元素
(3)選中控制檯的元素,滑鼠右鍵,在copy裡,選中“Copy XPath”
(4)copy的內容:(//*[@id="kw"])
5、注意find_elements和find_elements的區別!!!
好了,時間不多了,天也很晚了,大致就這些吧,今天就給小夥伴們就說到這裡吧。
巨集哥不能保證所整理都符合大家的口味,但我能保證每一篇都是用心去寫和用心去整理,我始終認同“分享的越多,你的價值增值越大”,歡迎大家關注我的部落格和個人公眾號的技術分享。在分享中進步,越努力越幸運,期待我們都有美好的明天!
有的小夥伴們等不急了,留言催巨集哥了,不好意思哈,巨集哥說實話最近特變的忙,沒時間更新,這還是點燈熬油趕了一篇,能力有限,希望大家喜歡!!!
支援巨集哥的朋友們和巨集哥的巨集粉記得點波推薦哦,您的肯定就是我進步的動力。鄙人先在這裡給您道謝了,謝您嘞~~
個人公眾號
微信群