Appium(十):元素定位(增強版)

1. 元素定位

寫完上一篇元素定位的博客,發現實用性基本爲零。這幾天真的煩死我了,一直在找資料,還去看了一遍appium官網文檔。最後結合着selenium的定位方法,測試出幾種可行的元素定位方法。android

1.1 層級定位

什麼是層級定位呢?web

在不少的自動化中若是隻是靠簡單的定位是沒有辦法完成自動化的。有的元素的id、name、className都是同樣的,xpath定位效率低下,而且在appium中,可使用的屬性很是少,這個時候咱們就須要使用層級定位了。數組

 

咱們能夠看到,QQ天氣和微視的class都是相同的, 接下來咱們用代碼試一試。app

# coding:utf-8
from appium import webdriver
from time import sleep

# 初始化
desired_caps = {}
# 使用哪一種移動平臺
desired_caps['platformName'] = 'Android'
# Android版本
desired_caps['platformVersion'] = '5.1.1'
#使用adb devices -l 查詢,當有多臺設備時,須要聲明
desired_caps['deviceName'] = '127.0.0.1:62001'
#包名
desired_caps['appPackage'] = 'com.tencent.mobileqq'
#界面名
desired_caps['appActivity'] = '.activity.SplashActivity'
#不清除數據
desired_caps['noReset'] = 'True'
# 啓動服務
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)

driver.find_element_by_id('com.tencent.mobileqq:id/recent_chat_list')
driver.find_element_by_class_name('android.widget.LinearLayout').click()

#退出driver
driver.quit()

運行後,咱們會發現代碼執行了,也沒有報錯,可是也不會點擊,這是爲何呢。這就牽扯到另一個定位問題,就是下面要說的List定位。測試

1.2 List定位

list顧名思義就是一個列表。當咱們想要獲取一個元素,可是卻發現符合條件的元素有不少個的時候,咱們就能夠選擇List定位了。由於元素的個數的不肯定性,因此咱們的方法也須要變成複數,因此這裏須要用複數,因此在咱們定位時咱們不可以接着用find_element_by_class_name等等定位方式了,咱們須要用他的複數形式find_elements_by_class_name,全部的定位方式都同樣須要採用複數加s。ui

driver.find_element_by_id('com.tencent.mobileqq:id/recent_chat_list')
driver.find_elements_by_class_name('android.widget.LinearLayout')

上面的代碼最後選擇的是com.tencent.mobileqq:id/recent_chat_list父節點下全部android.widget.LinearLayout子節點,如今咱們如何去操做這些子節點呢,有兩種方法:spa

一、List是一個集合,這裏定位的全部子節點最後就成了個list,若是咱們要訪問這個list裏面的某一個元素咱們能夠像訪問數組中的數據同樣經過下標訪問。最後的代碼就是下面這個樣子:.net

driver.find_element_by_id('com.tencent.mobileqq:id/recent_chat_list')
elements = driver.find_elements_by_class_name('android.widget.LinearLayout')
elements[0].click()
#讓咱們更好的觀看效果
sleep(5)

二、若是你要訪問List裏面的元素,那麼咱們是否能夠經過for循環語句來依次訪問呢?這個在自動化中會常常用到。下面你能夠經過這個思路本身去實戰一下,看可否達到預期效果。下面看個人代碼:code

for element in elements:
    sleep(2)
    element.click()

看上面的代碼,咱們經過循環去訪問這個list裏面的每個元素,由於每次循環獲得的都是其中一個元素,那麼咱們只須要在這個元素上加上你想要的操做便可,因此咱們這裏能夠直接點擊進去。orm

可是咱們會發現,在進入到第一個標籤後,系統就會報錯,爲何呢?由於界面跳轉到微視裏面了,而裏面沒有android.widget.LinearLayout元素,因此就會由於找不到元素而報錯。

因此這種方法的使用有限制,只能在那種不須要界面跳轉的狀況下使用。

1.3 xpath定位(補充)

xpath定位能夠分爲兩種,絕對定位和相對定位。

可是咱們會發現,絕對定位的路徑很是的長,後期代碼也比較麻煩,開發中幾乎不可能使用。(老大看到了就叼你)

相對路徑就是很是好用的一種了,不斷簡短,後期維護代碼也方便。

如下就是相對路徑的使用了:

我使用的是taptap軟件來進行測試,你們能夠換成其餘軟件。

(1) 若是當前class內存在惟一text能夠定位元素,直接用當前class+text,例如:

# coding:utf-8
from appium import webdriver
from time import sleep
from appium.webdriver.common.touch_action import TouchAction

# 初始化
desired_caps = {}
# 使用哪一種移動平臺
desired_caps['platformName'] = 'Android'
# Android版本
desired_caps['platformVersion'] = '5.1.1'
#使用adb devices -l 查詢,當有多臺設備時,須要聲明
desired_caps['deviceName'] = '127.0.0.1:62001'
#包名
desired_caps['appPackage'] = 'com.taptap'
#界面名
desired_caps['appActivity'] = 'com.play.taptap.ui.MainAct'
#不清除數據
desired_caps['noReset'] = 'True'
#啓動服務
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)

element = driver.find_element_by_xpath('//android.widget.TextView[@text="排行"]')
TouchAction(driver).tap(element).perform()

sleep(5)

#退出driver
driver.quit()

(2) 若是當前class內,resource-id、text二者能惟必定位元素,直接用當前class+二者並列,例如:

element1 = driver.find_element_by_xpath('//android.widget.TextView[@text="個人遊戲"]')
TouchAction(driver).tap(element1).perform()
sleep(2)
element2 = driver.find_element_by_xpath('//android.widget.TextView[@resource-id="com.taptap:id/app_title" and @text="第五人格T"]')
TouchAction(driver).tap(element2).perform()
sleep(5)

(3) 若是當前class內,text中的文本內容不是徹底符合,但能匹配部份內容,可用當前class+模糊定位contains,例如:

element = driver.find_element_by_xpath('//android.widget.TextView[contains(@text,"個人")]')
TouchAction(driver).tap(element).perform()
sleep(2)

還有不少相似的定位方法,能夠查看我找到的一個大佬寫的博客:https://blog.csdn.net/Dome_/article/details/80638245

整體上就這樣了,之後若是找到更好的方法,就再更新一章。

相關文章
相關標籤/搜索