Appium常用操作之「Toast提示信息獲取」
堅持原創輸出,點擊藍字關注我吧
作者:清菡
博客: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 信息要滿足以下四個要求:
- Appium server 版本 1.6.3+才支持 Toast 獲取。(而 Appium Server 1.6.3 沒有可視化界面,解決方案:下載 Appium-desktop-Setup-1.4.1-ia32.exe)。
- 代碼中必須指定 automationName 為:UIAutomator2
- UIAutomator2 只支持安卓版本 5.0+
因此,因為他們的最高支持安卓版本為 4.4.2,可以使用 genymotion 模擬器。
- 要求安裝 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('//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+原創文章,歡迎關注、交流,禁止第三方擅自轉載。
感謝支持清菡原創,歡迎點擊在看和轉發!