做者:清菡
博客:Oschina、雲+社區、知乎等各大平臺都有。web
安卓 4.4 以上的版本都是基於 UiAutomator
,如今已經改成 UiAutomator2
了。因此 Toast 在原來的 UiAutomator
基礎上沒辦法識別,無法識別的話就須要利用 UiAutomator2
了。app
如圖是 V1.10.0,以前的 Appium 版本中沒有看到過它會自動把自動化測試引擎從 Appium 切換到 UiAutomator2
,能夠去看下啓動日誌。若是版本低於 v1.10.0,版本比較舊的話,應該是沒有這種提示信息的。測試
因此在不少版本當中,若是咱們要用 Toast,咱們就須要指明一個東西:那就是自動化測試引擎必須指明爲 UiAutomator2。 否則它默認就不用這個,必須本身指明。可是如今已經作了改革了,會自動切換爲 UiAutomator2
。ui
automationName 是咱們的desired_caps
當中明確要指明的。若是想要獲取到 Toast 也是有要求的。日誌
Toast 是什麼?
code
UiAutomator Viewer 是抓不到它的。即便截屏截到了,用元素定位也是定位不到的。因此用正常套路是搞不定它的。orm
進行提示做用,且時間出現得很是短。基本上在全部的手機當中都是這種效果(包括驗證碼、或者註冊提示)。驗證碼提示,你也只能看着它,深灰色的背景,你不能點擊肯定、取消,沒有你能夠選項的地方也沒有你能夠輸入的地方。這個才叫作 Toast,由於長得比較別緻,UiAutomator Viewer 找不着它。server
咱們想要判斷一下這樣的 Toast 有沒有出現,通常這樣的 Toast 是帶有文字的。若是彈出的是個空白的 Toast 是沒有意義的,那麼你就能夠提 Bug 了。因此 Toast 裏面都是有內容的。ci
那這樣的Toast怎麼獲取呢?
element
既然不支持 UiAutomator,可是又有文字。就只能用一種方式來獲取,那就是 xpath。經過文本匹配來獲取(文本的所有匹配和部分匹配都是能夠的)。
你要獲取這樣的 Toast,證實它是存在的,就要有一些前置條件。
所以,由於他們的最高支持安卓版本爲 4.4.2,可使用 genymotion 模擬器。
Server 版本就是這個 v1.18.0:
desired_caps["automationName"]="UiAutomator2"
不然 Toast 是找不到的。
習慣性的操做是要等到元素可見以後,咱們纔會去操做它。新的東西出來,咱們的習慣都是等到它可見以後再去操做。由於它的時間很是短,因此間隔輪循週期作的很是短。
接下來須要作 Toast 的獲取,根據文本匹配,是經過 xpath 匹配。下面是須要注意的事情:
也就是等待的時候,要用元素存在的條件。不能用元素可見的條件。
driverWait
方法中,請用presence_of_element_located
。它存在了就好了,存在了以後再去處理它。
點擊 click 後出來文本要是手機號碼或者密碼不爲空。有時候以爲文本太長了,不想所有匹配。只想經過手機號碼這個文本匹配來找到它。
能夠,可是選取部份內容的時候要注意下:除了 xpath 以外,頁面上其它元素有沒有文本也是手機號碼的。
用這種 xpath 匹配手機號碼的話,優先匹配的是別人。不必定是你想匹配的手機號碼或密碼不能爲空了。
等到這執行的時候,人家早就消失了。等待的時候,人家早就消失了,那怎麼辦呢?
只能是縮短期或者不等待,直接去獲取一下。圖中,已經在執行,可是人家已經消失了。Toast 這個問題有些尷尬,若是特別須要 Toast 上面的消息怎麼辦?能夠求助開發,幫你稍微延長一點時間。
有時能找到 Toast,有時找不到,這裏是機率性的問題。目前對於 Toast 只有這一種獲取方式。
還有一個問題,Toast 獲取的時候提示你"應用的一些頁籤啊沒有經過",這個也是跟 Appium 的版本有關。Toast 這塊的問題是比較多的。
若是沒有 UIAutomator2
是絕對會失敗,即使你看到它出現了也必定會失敗。Server1.9 的時候獲取 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+原創文章,歡迎關注、交流,禁止第三方擅自轉載。
感謝支持清菡原創,歡迎點擊在看和轉發!