Appium之「元素定位和UiAutomator表達式」

堅持原創輸出,點擊藍字關注我吧

做者:清菡
博客:oschina、雲+社區、知乎等各大平臺都有。
html

目錄

  • 1、常見屬性的用法
    • 1.怎麼用 resource-id?
    • 2.其它屬性
  • 2、經過截圖就能夠看到元素的屬性,那怎麼元素定位呢?
    • 1.appium - app 頁面元素定位
    • 2.UiAutomator 的表達式
    • 3.何時用 UiAutomator 呢?
    • 4.和 Web 自動化的定位有啥區別?
  • 3、問題
    • 1.元素與屬性的區別?
    • 2.app 一進模擬器就崩潰
    • 3.若是遇到點擊 uiautomatorviewer 就閃退

1、常見屬性的用法

xpath 相對定位:若是相對定位中這個元素是有 id 的,這個 id 是惟一的,xpath 定位中優先經過 id 來定位。python

class 屬性對應的值是元素類型(是一個文本視圖工具),Web 自動化中元素類型表明 Input、image、button 這樣的標籤名。android

1.怎麼用 resource-id?

「resource-id 是惟一的,可是在 App 頁面中並不絕對惟一。大部分狀況下是惟一的,小部分狀況下是重複的。」web

若是一個頁面中,元素的樣式很是像,那頗有可能它們的 id 就是同樣的。UIAutomator Viewer 這個自帶的工具是不能看出這個 id 是否是絕對惟一的。正則表達式

「假設 resource-id 是惟一的,用相對定位這樣定位:」後端

和 Web 自動化同樣的玩法:元素類型[@屬性名稱=屬性值]微信

這裏的 class 不是 Web 網頁中的 class 屬性了,這裏表明它的標籤名和元素類型(它是一個圖片、一個文字、連接仍是一個按鈕呢?學會區分)。網絡

若是 resource-id 不是惟一的,那麼上面那個表達式是不夠的,還會追加到上層的 LinearlayoutRelativeLayout、包括祖先裏面的一些層級都會放進來。app

若是沒有安裝「升級 uiaumatorview-添加元素定位」就只能靠本身來判斷。看下其它和它長得很像、元素的格式、風格、樣式、頁面佈局都和它如出一轍的元素,看下各位的 id 是否全都是同樣的。框架

若是用了「升級 uiaumatorview-添加元素定位」,能夠根據它的表達式本身來判斷。

任何一個元素必定會有個 class,由於它是一個類別。Linearlayout 是同樣的,佈局也是安卓的控件,因此也會有控件名稱、控件類型。

如下這些東西只有 2 個值,False 和 True。

2.其它屬性

以上這些屬性在不少狀況下是沒有用的,可是在關鍵的時刻是頗有用的。

例如想篩選當前頁面中能夠滾動的元素,經過 scrollable 等於 True 來過濾。

2、經過截圖就能夠看到元素的屬性,那怎麼元素定位呢?

和 Web 自動化同樣的,都是經過元素屬性來定位,並且比 Web 自動化簡單。

App 中只支持 5 種元素定位方式。雖然繼承了 Web 自動化的元素定位,它之因此繼承呢,是用到了其中的一個部分。

1.appium - app 頁面元素定位

一、經過 id 定位元素:resrouce-id
二、經過 ClassName 定位:classname
三、經過 AccessibilityId 定位:content-desc
四、經過 AndroidUiAutomator 定位
五、經過 xpath 定位

與 Web 自動化通用的是 3 種:

一、經過 id 定位元素:resrouce-id
二、經過 ClassName 定位:classname
三、經過 xpath 定位

1.1經過 id 定位元素:resrouce-id
#id
driver.find_element_by_id("保密")

find_element_by_id()就有find_elements_by_id()

能夠找到多個,它的返回值同樣是列表。它的返回對象同樣是 Web element

源碼:

來自於這個文件:

在它的下面有個find_element_by_id()。它的方法和 Web 自動化是同樣的。

1.2第二種定位方式 ClassName,ClassName 就是這裏的 class 屬性。

雖然這裏表明的是元素類型,但它一樣是 class 屬性。

因此用這種方法就是這樣寫:
#class
driver.find_element_by_class_name("保密")

這裏有點區別,可是方法名仍是沒有區別的。這個 class 的屬性其實沒有多大用處,一個頁面中確定不少屬性的值和它很像的。因此這種用法很少。

既然是類別,圖片可能有好多種,輸入框也有好多種,它表明的是一種元素的類型。

「Web 自動化中 xpath 定位是最經常使用的,可是 App 自動化中 xpath 是最不想用的。緣由是它的效率過低了。」

「若是所有隻用 xpath 定位,問題會比較大,能不用 xpath 就不用 xpath」

1.3經過 AccessibilityId 定位

AccessibilityId 是移動端特有的定位方式。

from appium.webdriver.common.mobileby import MobileBy

這是以前看到的類,這個類當中除了繼承了 Web 自動化以外,對於安卓有 2 種,其中一種是ACCESSIBILITY_ID

源碼以下:

若是經過這種方式定位,對應的方式就是:

#content-desc
driver.find_element_by_accessibility_id()

此處應輸入 content-desc 的值,可是這裏是空的,因此不能經過它定位。

可是find_element_by_accessibility_id()是另一種 id,表明它在當前這個頁面中也是很獨特的。只要它有值,基本上能夠經過它來定位。

1.4經過 AndroidUiAutomator 定位

用的是安卓 UiAutomator 這個自動化框架中提供的元素定位方式。因此想用這種元素定位方式,就必須瞭解它究竟是怎麼作的。

UiAutomator 自動化庫是 Java 語言寫的,因此它的參數是 Java 代碼。UiAutomator 自動化庫提供了 text。而「元素有文本內容就能夠經過文本內容來定位。」

這個裏面的參數就必須是 UiAutomator 當中提供的定位方式。UiAutomator 是 Java 實現的,那麼它的定位類型確定也是 Java 實現的。

這個是谷歌開發中心的網址,有對 UiAutomator 的介紹:

https://developer.android.com/training/testing/ui-automator.html#ui-automator-viewer

UiAutomator 去定位元素的時候用的 UiSelector 類。Api 的官方文檔:

Appium 中經過 driver.find_element 來找元素的,找到的結果對象是一個 WebEmemt

「可是括號裏面,不一樣的定位類型你要輸入不一樣的定位表達式。」

UiSelector 是個 Java 類,主要用來作元素定位表達式。什麼來表明 UiSelector 中的 WebEmemt 呢?

經過 UiSelector 找到元素,這是表達式。總有一個方法經過它來找吧?

那就是 UiObject。UiObject 對應到 WebEmemt。WebEmemt 有對元素的各類操做以及屬性的獲取。「UiObject 就是 WebEmemt,有各類對元素的操做。」

UiObject 就能夠獲取這麼多的屬性:

經過 UiObject 對元素進行輸入、點擊等操做。

UiAutomator 是它本身的框架,因此對應的作了一套東西。UiSelector 這個類是用來表達元素定位的。UiAutomator 這裏的參數就是 UiSelector 類定位表達式。

Public constructors 公共的構造函數,構造函數就是初始化函數。類初始化的時候,有時候 init 是有參數的,構建函數當中就告訴了你它有沒有參數。

初始化的表達式:

UiSelector()

Java 中這樣寫:

new ui= UiSelector() 這就是表明類的實例化。

python 中這樣寫:

ui = UiSelector()

簡寫的作法:

new UiSelector()

有的時候並不用一個變量去接收它。在 Web 自動化當中,直接實例名稱.方法就能夠了。

在 Java 中不須要用一個變量去接收實例化對象,那就直接這樣寫new UiSelector().後面調它的各類方法。Java 中每個變量必須聲明變量類型,它是個布爾值,是個類仍是什麼。

事實上只有一個變量,叫作 val。

在這個地方,類也算一種數據類型。在 Python 中,類也算一種數據類型,是你本身構造的這種數據類型,只不過不須要聲明而已。

清一色的返回值基本都是類自己。

若是是一個實例化對象,那它的返回值都是實例化對象。每個實例化對象均可以有這麼多方法。

.checkable(true)返回值就是new UiSelector()。接下來能夠經過別的方式組合起來。

「多種條件組合起來對元素進行定位。有些元素的 id 不是惟一的,可是文本是惟一的。能夠純粹經過文本,也能夠 id 和文本一塊兒定位。」

resourceId 有 2 種方式:

「人家這裏是「字符串」,在 Java 中單引號和雙引號是有區別的。若是在 Java 中是字符串,只能用雙引號,否則就是報錯。」

new UiSelector().checkable(true).resourceId(「保密」)

經過 2 個屬性來定位的,一個是 checkable()。

一個是 resourceId()。二者都要知足才能符合個人定位表達。

匹配到正則表達式的元素也能夠。

text 提供了 4 種定位方式:

第一種:全局匹配(徹底文本匹配)。

new UiSelector().checkable(true).resourceId(「保密」).text(「個人」)

第二種:包含。

第三種:正則表達式的匹配。

textstartswith:以什麼開頭的一個字符串。

若是你的文本很長,能夠定義以什麼開頭,也能夠實現部分匹配。只不過這個部分匹配是有要求的,必須以什麼開頭。

這 4 種方式均可以用的,參數全是字符串。

除了 text 是文本性質的,content-desc 也是文本性質的。

content-desc 也提供了 4 種定位方式:

className:匹配一個控件的類型。

控件類型也屬於控件的屬性。你們都叫作控件,可是你叫這個名字,我叫那個名字。

每一個元素的 package 都是同樣的,因此 package 沒多大用處。

scrollable:除了 UiAutomator 能夠提供到位,xpath 也能夠作到可是有所欠缺。

UiAutomator 自動化庫提供了各類屬性。只要學會表達式,而後能本身判斷用什麼樣的類型來定位就行了。

2.UiAutomator 的表達式

使用 UiAutomator 中的 UiSelector 類來處理元素定位。

new UiSelector().函數名稱(「定位表達式」)

字符串是雙引號,布爾值就不是雙引號了。

driver.find_element_by_android_uiautomator('new UiSelector().resourceId("保密").text("個人")')#這種用法,外面只能用單引號或者裏面的雙引號打個斜槓標明下

實際上只經過 text 定位就能夠了。除了它叫作」個人「,這個頁面也沒有別人叫作」個人「了。

因此改爲這樣:
# UiAutomator
driver.find_element_by_android_uiautomator('new UiSelector().text("個人")')#這種用法,外面
# 只能用單引號或者裏面的雙引號打個斜槓標明下

3.何時用 UiAutomator 呢?

「若是經過 id 定位、ClassName 定位、AccessibilityId 定位這前 3 種方式都沒有讓你惟必定位到元素,那就用第 4 種呀!」

第 4 種其實效率很高的,由於是人家框架本身的定位方式呀,都不須要轉換。第 5 種 xpath 定位,寫法其實和 Web 自動化的 xpath 定位的寫法同樣。xpath 能幹的事,第 4 種方式就能所有搞定了。

以上 5 種都搞不定的狀況下,就須要用座標了。可是座標不太穩定,除非實在沒有辦法了才用座標,座標比 xpath 還差勁。

通常的 app 都有 id,若是你測得 app 沒有 id,那就去給開發提意見,把 id 加上。

4.和 Web 自動化的定位有啥區別?

app 自動化相對來講比較簡單。若是把「uiaumatorview 升級版」裝上了,全部的定位表達式就直接拷貝就行了。

「不須要調試也不須要考慮上下級關係,若是是比較規範的 app,經過 id 來定位就能夠了。」

和 Web 自動化的寫法同樣。4 大屬性都同樣(點擊、輸入、獲取元素的文本內容、獲取元素的屬性)。函數名稱同樣,操做方式也同樣。須要等待,等待方法也和 Web 自動化同樣。

3、問題

1.元素與屬性的區別?

元素:

一對(或一個)標籤包含的範圍:其實能夠理解爲元素爲一個容器,而這容器裏面包含了標籤。

這裏的一對標籤:<body> </body>就是開始和結束標籤。

範圍:就是從開始標籤<body>到結束標籤</body> 下面那個矩形框架就是這裏的範圍。

圖片來自網絡,畫的很好

2. app 一進模擬器就崩潰

Appium 的 bug 比較多,須要換個版本試下,不要裝太老的或者最新的。隔 2-3 個版本換個試下。和操做系統也有關係,有時 win7 不行,win10 就能夠。

3.若是遇到點擊 uiautomatorviewer 就閃退

在 cmd 命令行中啓動 uiautomatorviewer.exe,命令行有的時候能夠看出來是什麼錯誤致使。通常是有衝突。還有看看你的安裝包裝全了沒有,好比 jdk、環境變量有沒有配置正確之類的。


公衆號「清菡軟件測試」首發,更多原創文章:清菡軟件測試 88+原創文章,歡迎關注、交流,禁止第三方擅自轉載。




精彩推薦




更新「Appium運行原理」講解!
Ui Automator 框架和Ui Automator Viewer你會用嗎?附送「必備adb命令」拿走不謝 !
舉個華爲計算器的栗子「Appium環境配置與調試」
怎麼安裝配置ADB環境?
pytest的fixture怎麼用?
Python+Appium運行簡單的demo,你須要理解Appium運行原理!
Web自動化必會知識:「Web基礎、元素定位、元素操做、Selenium運行原理、項目實戰+框架」
使用Typora+PicGo配置Gitee圖牀
持續集成有什麼好處?快來看鴨
按F12,你真的會準肯定位先後端問題嗎?

感謝支持清菡原創,歡迎點擊在看轉發

本文分享自微信公衆號 - 清菡軟件測試(qinghanTester)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索