對於自動化測試來講,核心技能就是對象的定位了。無論是web頁面上的按鈕或輸入框,仍是移動app上的一個按鈕或輸入框,咱們要想對其進行點擊或輸入操做,前提是要先找到這個對象。css
webdriver提供了八種元素定位的方法:python
- id
- name
- class name
- tag name
- link text
- partial link text
- xpath
- css selector
在python語言中對應的定位方法以下:android
find_element_by_id()ios
find_element_by_name()web
find_element_by_class_name()app
find_element_by_tag_name()學習
find_element_by_link_text()測試
find_element_by_partial_link_text()ui
find_element_by_xpath()spa
find_element_by_css_selector()
一組元素定位的方法以下:
find_elements_by_id()
find_elements_by_name()
find_elements_by_class_name()
find_elements_by_tag_name()
find_elements_by_link_text()
find_elements_by_partial_link_text()
find_elements_by_xpath()
find_elements_by_css_selector()
Appium徹底繼承了WebDriver中所定義的這些方法,除此以外對其進行了擴展,以便適合移動端對象的定位與操做。
由Mobile JSON Wire Protocol協議中定義的方法,更適合移動設備上的控件定位。
對於python來講,在WebDriver的方法的基礎上增長了下列方法:
find_element_by_accessibility_id()
find_elements_by_accessibility_id()
find_element_by_android_uiautomator()
find_elements_by_android_uiautomator()
可是咱們對照查詢到的元素,能夠發現不少的定位方法沒法實現。
點擊審查元素,發現根本就沒有name什麼的,最多的仍是class、id元素。
因此咱們只須要學習id、class、xpath定位就能夠完成定位元素的目的了。
通過我幾回測試,發現app的id值有兩個屬性能夠表示,分別是id和resource-id。
若是id只有一個,那麼就使用find_element_by_id來查詢。
# coding:utf-8 import time from appium import webdriver # 初始化 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.android.settings' # com.tencent.mobileqq #界面名 desired_caps['appActivity'] = '.Settings' # 啓動服務 driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) driver.find_element_by_id('com.android.settings:id/search').click() time.sleep(5) driver.quit()
啓動這個程序,咱們能夠看到點擊了搜索按鈕,進入了搜索界面。
而id值不是每一個元素都會顯示的,而resource-id能夠查詢到,可是在大多數時候resource-id是一系列元素的id,因此咱們須要使用find_elements_by_id方法來查詢id。
# coding:utf-8 import time from appium import webdriver # 初始化 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.android.settings' # com.tencent.mobileqq #界面名 desired_caps['appActivity'] = '.Settings' # 啓動服務 driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) titles = driver.find_elements_by_id("com.android.settings:id/title") for title in titles: print(title.text) time.sleep(5) driver.quit()
class通常都不止一個,因此應該須要遍歷一遍獲得的元素,而後縮小搜索條件來得到目標元素。
咱們能夠藉助python中的pop()方法肯定想要這一組元素中的第幾個,並對它進行點擊或輸入操做。
pop(0) 或pop(-1):默認得到一組元素中的最後一個。
pop(n):得到一組元素中的第n-1個。
一個class元素,使用find_element_by_class_name來查詢。
# coding:utf-8 import time from appium import webdriver # 初始化 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.android.settings' # com.tencent.mobileqq #界面名 desired_caps['appActivity'] = '.Settings' # 啓動服務 driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) driver.find_element_by_id('com.android.settings:id/search').click() driver.find_element_by_class_name("android.widget.EditText").send_keys("hello") time.sleep(5) driver.quit()
能夠看到點擊搜索按鈕後出現後,在輸入框輸入了hello。
若是class元素有不少,就可使用find_elements_by_class_name來查詢。
# coding:utf-8 import time from appium import webdriver # 初始化 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.android.settings' #界面名 desired_caps['appActivity'] = '.Settings' # 啓動服務 driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) text_views = driver.find_elements_by_class_name("android.widget.TextView") for text_view in text_views: print(text_view.text) time.sleep(5) driver.quit()
在webdriver上xpath定位是功能強大的一種定位方式。我我的慣用於此方法來定位web頁面上的元素。可是在android上要定位的是控件,而非頁面元素,xpath定位的寫法也會有所不一樣。
# coding:utf-8 import time from appium import webdriver # 初始化 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.android.settings' # com.tencent.mobileqq #界面名 desired_caps['appActivity'] = '.Settings' # 啓動服務 driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) driver.implicitly_wait(5)#隱式等待,下一章會講解 driver.find_element_by_id("com.android.settings:id/search").click() driver.find_element_by_class_name("android.widget.EditText").send_keys("hello") driver.find_element_by_xpath("//*[@content-desc='收起']").click() time.sleep(5) driver.quit()
就目前而言吧,我以爲appium的xpath定位很很差使用,多是由於還不夠熟練的緣由吧。
# coding:utf-8 import time from appium import webdriver # 初始化 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.android.settings' # com.tencent.mobileqq #界面名 desired_caps['appActivity'] = '.Settings' # 啓動服務 driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) elements = driver.find_elements_by_xpath("//*[contains(@text,'設')]") for element in elements: print(element.text) time.sleep(5) driver.quit()
和webdriver同樣,若是使用find_element_by_xx方法,若是傳入一個沒有的特徵,會報NoSuchElementException的錯誤。若是使用find_elements_by_xx方法,若是傳入一個沒有的特徵,不會報錯,會返回一個空列表。