目錄
一、前言
1、Appium元素定位
1.1、Android頁面介紹
2、App常用元素定位
1.1、id定位
1.2、UIAutomator定位
1.3、Xpath定位
1.4、content-desc定位
1.5、className定位
1.6、擴展
3、App元素定位方法調用
一、前言
App自動化測試時定位元素的方式與Web自動化相似,也是通過id、class等去定位,但也有很多不同的地方。
1、Appium元素定位
Appium 和 Selenium 定位方式的區別:
定位方式 |
Appium |
Selenium |
說明 |
id |
resource-id |
id |
唯一性較強的定位方式;HTML中具有唯一性,但在App中不一定是唯一的 |
class name |
class |
class |
HTML 中的 class 為 css 樣式類,而 App 中表示控件類型 |
name |
無 |
name |
Appium 1.5 以前 name 定位使用 text 屬性,1.8 以后取消 |
Accessibility id |
content-desc |
無 |
盲人模式,輸入時語音提示(Android中獨有的定位方式) |
xpath |
使用class表示層級 |
使用標簽名表示層級 |
Appium定位表達式://android.widget.TextView[@resource-id="com.moji.mjweather:id/cm3"] |
css selector |
無 |
css 選擇器語法 |
|
UIAutomator |
使用 Android 官方測試框架 UIAutomator 定位 |
無 |
Android 獨有定位方式 |
其余 selenium 中的定位方式,如:tag_name 、link_text 等,在 Appium 中不存在。
1.1、Android頁面介紹
1.1.1、App元素定位class說明
Appium 中的 class name 定位方式針對的是 class 屬性。而在 Android 中的 class 指的是該控件的類型,就像 HTML 中的標簽類型。
所以 Appium 中的 class name 定位其實就等價於 Selenium 中的 tag name(標簽名)定位。除了在某些特定情況下適用而外,其他絕大多數時候都很難定位到唯一的元素。
1.1.2、Android頁面控件
Android頁面控件類型 |
||
控件名稱 |
中文釋義 |
功能 |
ImageView |
圖片控件 |
用來顯示圖片 |
TextView |
文本輸入框 |
展示文字/文本 |
Button |
按鈕 |
用戶通過點擊button觸發一系列的事件 |
EditText |
編輯框 |
接受用戶輸入的數據 |
CheckBox |
復選框 |
復選/多選 |
ProgressBar |
進度條 |
加載進度條,表示正在加載某一些數據 |
Switch |
開關控件 |
左滑、右滑表示開啟關閉 |
RatingBar |
評分條 |
星星樣式的評分條 |
SeekBar |
拖動條 |
例如調節手機屏幕亮度的拖動條 |
Toast |
彈出組件 |
Toast提示語 |
WebView |
內嵌網頁 |
App中內嵌web網頁,也就是H5頁面 |
1.1.3、Android頁面布局
Android頁面布局類型 |
||
控件名稱 |
中文釋義 |
功能 |
FrameLayout |
框架布局 |
所有控件都被放置在最左上的區域; 下一個子控件會重疊覆蓋上一個控件。 |
LinearLayout |
線性布局 |
控件的排序方式:垂直/水平 |
AbsoluteLayout |
絕對布局 |
采用坐標軸的方式定位控件; 左上角原點(0,0),往右X軸遞增,往下Y軸遞增。 |
RelativeLayout |
相對布局 |
根據參照物(某控件)的位置,來確定控件的位置 |
TableLayout |
表格布局 |
通過表格方式(行,列)布局控件位置 |
1.1.4、Android坐標系統
Android坐標系以手機屏幕左上角的頂點為坐標原點,從該點向右為x軸正方向,從該點向下為y軸正方向。
在觸控事件中,使用getRawX()和getRawY()方法獲取的坐標,就是以這個坐標系為標准下的坐標值。
2、App常用元素定位
1.1、id定位
Id是一個控件的唯一標識,如果一個元素有對應的resource-id,我們就可以采用這種方式來實現元素定位操作;但是實際開發中,也有可能app項目的開發人員不是很嚴謹,一個頁面有很多個相同的id,就需要其他方式定位。
實例:(取resource-id的值)
driver.find_element_by_id("com.wuba.zhuanzhuan:id/azo")
也可以直接用id后面的內容:
driver.find_element_by_id("azo")
1.2、UIAutomator定位
Uiautomator元素定位是Android系統原生支持的定位方式,雖然與xpath相似,但是比xpath更快,且支持元素的全部屬性定位。定位原理是通過Android自帶的Android Uiautomator的類庫去查找元素。Appium元素定位方法其實也是基於Uiautomator來進行封裝的。
1.2.1、常用的定位方式有:
id:對應Android屬性的resource_id
driver.find_element_by_android_uiautomator('new UiSelector().resourceId(\"com.tencent.mm:id/e4c\")')
text:對應Android的text
driver.find_elements_by_android_uiautomator('new UiSelector().text(\"+關注\")')
classname:對應Android屬性的class
driver.find_element_by_android_uiautomator('new UiSelector().className(\"android.widget.Button\")')
1.2.2、Uiautomator定位格式:
只通過id、或text、或classname其中一種方式定位
'new UiSelector().resourceId(\”****\”)’
通過多種條件同時滿足的方式定位
'new UiSelector().resourceId(\”****\”). className(\”****\”)’
這種方式為鏈式調用,表示同時滿足resourceId和className
###注意:java中字符串必須用雙引號” ”
1.3、Xpath定位
xpath其實就是一個path(路徑),一個描述頁面元素位置信息的路徑,相當於元素的坐標。xpath基於XML文檔樹狀結構,是XML路徑語言,用來查詢xml文檔中的節點,既可以用於XML,也可以用於HTML。
使用方式與web自動化測試的Xpath定位差不多,但是text文本使用不一樣:在App自動化當中text是用@text表示,web自動化用的是text()。
實例:
# 沒有contains時,屬性和值之間用 =
driver.find_element_by_xpath('//android.widget.Button[@resource-id=\"com.tencent.mm:id/e4c\"]')
driver.find_element_by_xpath('//*[@text="請輸入用戶名"]')
# 有contains時,屬性和值之間用,中間可以用and
driver.find_element_by_xpath('//*[contains(@text,"登錄") and contains(@index,"5")]')
Appium 對於 xpath 定位執行效率是比較低的,一般情況下盡量不用這個定位方式。
注意:HTML中使用text文本定位時,與app的定位表達式不同,HTML中的表達式為://a[text()='新聞'],App中text前面要加@符號。
1.4、content-desc定位
某個元素屬性: content-desc = “option_selected_icon”
上面的content-desc元素,可以有多種方式進行定位:
方式一:使用 find_element_by_accessibility_id 定位
driver.find_element_by_accessibility_id('option_selected_icon')
方式二:使用 find_element_by_android_uiautomator 定位
driver.find_element_by_android_uiautomator('new UiSelector().description("option_selected_icon")')
方式三:使用 xpath 定位
driver.find_element(By.XPATH, '//*[@content-desc="option_selected_icon"]')
1.5、className定位
class屬性一般不唯一,多半用在復數定位,className復數定位。
某個元素屬性:class = "android.widget.Button"
定位表達式:
driver.find_element_by_class_name("android.widget.Button")
1.6、擴展
通過text定位
1、通過text文本定位語法
new UiSelector().text("text文本")
2、文本比較長的時候,可以用textContains模糊匹配,只要文本包含匹配內容就可以了。
new UiSelector().textContains("包含text文本")
3、textStartsWith是以某個文本開頭的匹配
new UiSelector().textStartsWith("以text文本開頭")
4、正則匹配textMatches,這個需要配合正則表達式,就不舉例了。
new UiSelector().textMatches("正則表達式")
索引instance()定位
在通過UiSelector定位元素時,如果匹配到多個元素,可以通過索引選擇需要的那個
'new UiSelector().className(\"android.widget.Button\").instance(2)'
注意:這里的索引值不是頁面元素索引index,是UiSelector()方法查找的所有元素索引。
組合定位,一般組合用id、class、text這三個屬性會比較好一點
例:id+class 屬性組合
id_class = 'resourceId("com.xyh.commerce:id/ll_personal").className("android.widget.LinearLayout")' driver.find_element_by_android_uiautomator(id_class).click()
父子定位childSelector
有時候不能直接定位某個元素,但是它的父元素很好定位,這時候就先定位父元素,通過父元素找兒子。
element = 'resourceId("com.xyh.commerce:id/ll_personal").childSelector(text("我的"))' driver.find_element_by_android_uiautomator(element)
兄弟定位fromParent
有時候父元素不好定位,但是跟他相鄰的兄弟元素很好定位,這時候就可以通過兄弟元素,找到同一父級元素下的子元素。
brother = 'resourceId("com.xyh.commerce:id/img_personal").fromParent(text("我的"))' driver.find_element_by_android_uiautomator(brother)
3、App元素定位方法調用
Python中App自動化元素定位方法的調用,與Web自動化調用的方法一致。