Appium常用操作之「Toast提示資訊獲取」

清菡發表於2020-11-20

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

作者:清菡

部落格:Oschina、雲+社群、知乎等各大平臺都有。

目錄

  • 一、什麼是 Toast
  • 二、獲取 Toast 提示資訊的前提
    • 1.針對這種元素,有的時候我們需要做什麼呢?
    • 2.要獲取 Toast 資訊要滿足以下四個要求
    • 3.怎麼看 Server 版本?
    • 4.如果 Appium Server 版本低於 1.6.3+,程式碼中必須指定 automationName 為 UIAutomator2
  • 三、4 點需要注意的事情
    • 1.在我們等待元素可見的時候,不要用 visibility_of_element_located,因為它對 Toast 的可見處理並不支援,會直接報錯命令無法執行。
    • 2.選取部分內容匹配需注意
    • 3.沒有找到匹配的 Toast
    • 4.Toast 獲取跟 Appium 的版本有關
  • 四、Toast 提示資訊獲取
  • 五、程式碼

一、什麼是 toast

安卓 4.4 以上的版本都是基於 UiAutomator,現在已經改為 UiAutomator2 了。所以 Toast 在原來的 UiAutomator 基礎上沒辦法識別,沒法識別的話就需要利用 UiAutomator2 了。

如圖是 V1.10.0,之前的 Appium 版本中沒有看到過它會自動把自動化測試引擎從 Appium 切換到 UiAutomator2,可以去看下啟動日誌。如果版本低於 v1.10.0,版本比較舊的話,應該是沒有這種提示資訊的。

所以在很多版本當中,如果我們要用 Toast,我們就需要指明一個東西:那就是自動化測試引擎必須指明為 UiAutomator2。 不然它預設就不用這個,必須自己指明。但是現在已經做了改革了,會自動切換為 UiAutomator2

automationName 是我們的desired_caps當中明確要指明的。如果想要獲取到 Toast 也是有要求的。

Toast 是什麼?

UiAutomator Viewer 是抓不到它的。即使截圖截到了,用元素定位也是定位不到的。所以用正常套路是搞不定它的。

進行提示作用,且時間出現得非常短。基本上在所有的手機當中都是這種效果(包括驗證碼、或者註冊提示)。驗證碼提示,你也只能看著它,深灰色的背景,你不能點選確定、取消,沒有你可以選項的地方也沒有你可以輸入的地方。這個才叫做 Toast,因為長得比較別緻,UiAutomator Viewer 找不著它。

二、獲取 Toast 提示資訊的前提

1.針對這種元素,有的時候我們需要做什麼呢?

我們想要判斷一下這樣的 Toast 有沒有出現,一般這樣的 Toast 是帶有文字的。如果彈出的是個空白的 Toast 是沒有意義的,那麼你就可以提 Bug 了。所以 Toast 裡面都是有內容的。

那這樣的Toast怎麼獲取呢?

既然不支援 UiAutomator,但是又有文字。就只能用一種方式來獲取,那就是 xpath。通過文字匹配來獲取(文字的全部匹配和部分匹配都是可以的)。

你要獲取這樣的 Toast,證明它是存在的,就要有一些前置條件。

2.要獲取 Toast 資訊要滿足以下四個要求:

  1. Appium server 版本 1.6.3+才支援 Toast 獲取。(而 Appium Server 1.6.3 沒有視覺化介面,解決方案:下載 Appium-desktop-Setup-1.4.1-ia32.exe)。
  2. 程式碼中必須指定 automationName 為:UIAutomator2
  3. UIAutomator2 只支援安卓版本 5.0+

因此,因為他們的最高支援安卓版本為 4.4.2,可以使用 genymotion 模擬器。

  1. 要求安裝 jdk1.8 64 位及以上。配置其環境變數 JAVA_HOME 和 path。

3.怎麼看 Server 版本?

Server 版本就是這個 v1.18.0:

4.如果 Appium Server 版本低於 1.6.3+,程式碼中必須指定 automationName 為 UIAutomator2

desired_caps["automationName"]="UiAutomator2"

否則 Toast 是找不到的。

三、4 點需要注意的事情

習慣性的操作是要等到元素可見之後,我們才會去操作它。新的東西出來,我們的習慣都是等到它可見之後再去操作。因為它的時間非常短,所以間隔輪循週期做的非常短。

接下來需要做 Toast 的獲取,根據文字匹配,是通過 xpath 匹配。下面是需要注意的事情:

1.在我們等待元素可見的時候,不要用 visibility_of_element_located,因為它對 Toast 的可見處理並不支援,會直接報錯命令無法執行。

也就是等待的時候,要用元素存在的條件。不能用元素可見的條件。

driverWait 方法中,請用presence_of_element_located。它存在了就行了,存在了之後再去處理它。

2.選取部分內容匹配需注意

點選 click 後出來文字要是手機號碼或者密碼不為空。有時候覺得文字太長了,不想全部匹配。只想通過手機號碼這個文字匹配來找到它。

可以,但是選取部分內容的時候要注意下:除了 xpath 之外,頁面上其它元素有沒有文字也是手機號碼的。

用這種 xpath 匹配手機號碼的話,優先匹配的是別人。不一定是你想匹配的手機號碼或密碼不能為空了。

3.沒有找到匹配的 Toast

等到這執行的時候,人家早就消失了。等待的時候,人家早就消失了,那怎麼辦呢?

只能是縮短時間或者不等待,直接去獲取一下。圖中,已經在執行,但是人家已經消失了。Toast 這個問題有些尷尬,如果特別需要 Toast 上面的訊息怎麼辦?可以求助開發,幫你稍微延長一點時間。

有時能找到 Toast,有時找不到,這裡是概率性的問題。目前對於 Toast 只有這一種獲取方式。

4.Toast 獲取跟 Appium 的版本有關

還有一個問題,Toast 獲取的時候提示你"應用的一些頁籤啊沒有通過",這個也是跟 Appium 的版本有關。Toast 這塊的問題是比較多的。

如果沒有 UIAutomator2 是絕對會失敗,即便你看到它出現了也一定會失敗。Server1.9 的時候獲取 Toast 是沒有問題的。

四、Toast 提示資訊獲取

xpath 表示式是固定的,現在主要用的方式是文字匹配(部分、全部都可以)。那這個表示式就是雙斜槓(相對定位)。

xpath = '//*[contains(@text,"部分文字內容")]'

這個表示式是固定的。只要把 toast 對應的文字資訊替換下就可以了。

#獲取toast內容是否出現
def toast_exist(self, toastmessage):
    toast_loc = ("xpath", "//*[contains(@text,'%s')]" % toastmessage)
    try:
    WebDriverWait(self.driver,5,0.2).until(EC.presence_of_element_located(toast_loc))
      #獲取文字內容
      driver.find_element_by_xpath(toast_loc).text
      return True
    except:
      return False

五、程式碼


from appium import webdriver
# from time import sleep
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from appium.webdriver.common.mobileby import MobileBy

desired_caps={}

# 自動化測試引擎
# desired_caps["automationName"]="UiAutomator2"

# 平臺型別
desired_caps["platformName"]="Android"
# 平臺版本號
desired_caps["platformVersion"]="10"
# 裝置名稱
desired_caps["deviceName"]="2NSDU20410017297"
# app 包名
desired_caps["appPackage"]="輸入appPackage"
# app 入口 acitivity
desired_caps["appActivity"]="輸入activity"

# 連線Appium server。前提:appium desktop要啟動。有監聽埠。
# 將desired_caps傳送給appium server。開啟app
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps)

# 執行程式碼之前:
#1.appium server啟動成功。處於監聽狀態
#2.模擬器/真機必須能夠被電腦識別。即adb devices能夠識別到要操作的裝置。

# 點選“我的”
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ID,"com.lemon.lemonban:id/navigation_my")))
driver.find_element_by_id('com.lemon.lemonban:id/navigation_my').click()

# # 點選“我的頭像”
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ID,"com.lemon.lemonban:id/fragment_my_lemon_avatar_layout")))
driver.find_element_by_id("com.lemon.lemonban:id/fragment_my_lemon_avatar_layout").click()

#點選手機密碼登入
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ID,'com.lemon.lemonban:id/btn_login')))
driver.find_element_by_id('com.lemon.lemonban:id/btn_login').click()

# 1.xpath表示式、文字匹配
loc='//*[contains(@text,"{}")]'.format("手機號碼或密碼")

# 等待的時候,要用元素存在的條件。不能用元素可見的條件。
try:
    WebDriverWait(driver,10,0.01).until(EC.presence_of_elements_located((MobileBy.XPATH,loc)))
    # 上限10秒就夠了,確認toast在頁面上存在的時候大概是多久,它都沒有0.5秒,你去間隔0.5,可能消失了,你還只留在這。
    print(driver.find_element_by_xpath(loc).text)
except:
    print("沒有找到匹配的toast!!!!")


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

感謝支援清菡原創,歡迎點選在看和轉發!

相關文章