做者:清菡
博客: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+原创文章,欢迎关注、交流,禁止第三方擅自转载。
感谢支持清菡原创,欢迎点击在看和转发!