Toast简介
Android中的Toast是一种简易的消息提示框。 当视图显示给用户,在应用程序中显示为浮动。和Dialog不一样的是,它永远不会获得焦点,无法被点击。
Toast类的思想就是尽可能不引人注意,同时还向用户显示信息,希望他们看到。而且Toast显示的时间有限,一般3秒左右就消失了。因此使用传统的元素定位工具,我们是无法定位到Toast元素的(传说中低调奢华有内涵)。
Appium Toast内容获取
Add ability to verify TOAST messages (these can't be interacted with, only text retrieval allowed)
1.Appium 1.6.3开始支持识别Toast内容,主要是基于UiAutomator2,因此需要在Capablity配置如下参数:
'automationName':'uiautomator2'
或者:
desired_caps['automationName']='uiautomator2'
2.安装appium-uiautomator2-driver: 安装命令如下:
cnpm install appium-uiautomator2-driver
安装成功后可以在 C:\Users\Administrator\node_modules看到对应的文件:
_appium-uiautomator2-driver@1.12.0@appium-uiautomator2-driver
_appium-uiautomator2-server@1.10.0@appium-uiautomator2-server
代码实现
步骤一:初始化
在capability配置内部增加:desired_caps[‘uiautomationName’]=’ uiautomator2’
步骤二:定位toast元素
(1)定义toast文本内容
(2)定义路径
(3)组合文本内容和路径进行定位:用format()连接路径和文本内容
参考代码
导入模块
11 from appium import webdriver
12 from selenium.common.exceptions import NoSuchElementException
13 from selenium.webdriver.support.ui import WebDriverWait
14 from selenium.webdriver.support import expected_conditions as EC
15
16 desired_caps = {'platformName': 'Android',
17 'platforVersion': '5.1.1',
18 'automationName': 'Uiautomator2',
19 'deviceName': '127.0.0.1:62001',
20 'app': r'C:\Users\DELL\Downloads\kaoyanbang.apk',
21 'appPackage': 'com.tal.kaoyan',
22 'appActivity': 'com.tal.kaoyan.ui.activity.SplashActivity',
23 'noReset': 'True'}
24
25 driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
26 driver.implicitly_wait(9)
27 try:
28 driver.find_element_by_id("android:id/button2").click()
29 except NoSuchElementException:
30 print(1)
31 try:
32 driver.find_element_by_id('com.tal.kaoyan:id/tv_skip').click()
33 except NoSuchElementException:
34 print(2)
35 driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').clear()
36 driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').send_keys('bjhongge')
37
38 driver.find_element_by_id('com.tal.kaoyan:id/login_password_edittext').send_keys('1213213')
39 driver.find_element_by_id('com.tal.kaoyan:id/login_login_btn').click()
40
41 error_message = "用户名或密码错误,你还可以尝试3次"
42 limit_message = "验证失败次数过多,请15分钟后再试"
43
44 message = '//*[@text=\'{}\']'.format(error_message)
45 #message='//*[@text=\'{}\']'.format(limit_message)
46
47 toast_element = WebDriverWait(driver, 15).until(lambda x:x.find_element_by_xpath(message))
48 print(toast_element.text)
说明:
连接不同的类型的变量或内容format()
显示等待:webdriver(driver,5)
driver是webdriver的驱动程序,5是超时时间,以秒为单位
WebDriverWait()一般由 until()或 until_not()方法配合使用,下面是 until()和 until_not()方法的说明。
until(method, message=’’)
调用该方法提供的驱动程序作为一个参数,直到返回值不为 False。
until_not(method, message=’’)
调用该方法提供的驱动程序作为一个参数,直到返回值为 False。
动态函数:lambda x:x+5
X是函数的参数,冒号后面是函数的返回值
封装toast判断
1.单独写一个函数来封装判断是否存在toast消息,存在返回True,不存在返回False
1 def is_toast_exist(driver,text,timeout=30,poll_frequency=0.5):
2
3 '''is toast exist, return True or False
4
5 :Agrs:
6
7 - driver - 传driver
8
9 - text - 页面上看到的文本内容
10
11 - timeout - 最大超时时间,默认30s
12
13 - poll_frequency - 间隔查询时间,默认0.5s查询一次
14
15 :Usage:
16
17 is_toast_exist(driver, "看到的内容")
18
19 '''
20
21 try:
22
23 toast_loc = ("xpath", ".//*[contains(@text,'%s')]"%text)
24
25 WebDriverWait(driver, timeout, poll_frequency).until(EC.presence_of_element_located(toast_loc))
26
27 return True
28
29 except:
30
31 return False
#
WebDriverWait 方法后面有两种等待方式
until
- method: 在等待期间,每隔一段时间(__init__中的poll_frequency)调用这个传入的方法,直到返回值不是False
- message: 如果超时,抛出TimeoutException,将message传入异常
until_not
- until相反,until是当某元素出现或什么条件成立则继续执行,
- until_not是当某元素消失或什么条件不成立则继续执行,参数也相同,不再赘述。
WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)
10).until(driver.find_element_by_id('kw')) # 错误
以下两个条件类验证title,验证传入的参数title是否等于或包含于driver.title
title_is
title_contains
以下两个条件验证元素是否出现,传入的参数都是元组类型的locator,如(By.ID, ‘kw’)
顾名思义,一个只要一个符合条件的元素加载出来就通过;另一个必须所有符合条件的元素都加载出来才行
presence_of_element_located
presence_of_all_elements_located
以下三个条件验证元素是否可见,前两个传入参数是元组类型的locator,第三个传入WebElement
第一个和第三个其实质是一样的
visibility_of_element_located
invisibility_of_element_located
visibility_of
以下两个条件判断某段文本是否出现在某元素中,一个判断元素的text,一个判断元素的value
text_to_be_present_in_element
text_to_be_present_in_element_value
以下条件判断frame是否可切入,可传入locator元组或者直接传入定位方式:id、name、index或WebElement
frame_to_be_available_and_switch_to_it
以下条件判断是否有alert出现
alert_is_present
以下条件判断元素是否可点击,传入locator
element_to_be_clickable
以下四个条件判断元素是否被选中,第一个条件传入WebElement对象,第二个传入locator元组
第三个传入WebElement对象以及状态,相等返回True,否则返回False
第四个传入locator以及状态,相等返回True,否则返回False
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
最后一个条件判断一个元素是否仍在DOM中,传入WebElement对象,可以判断页面是否刷新了
staleness_of
确认新窗口打开
new_window_is_opened
上面是所有17个condition,与until、until_not组合能够实现很多判断,如果能自己灵活封装,将会大大提高脚本的稳定性
封装后参考代码
1 # coding=utf-8
2 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
3
4 # 2.注释:包括记录创建时间,创建人,项目名称。
5 '''
6 Created on 2019-7-31
7 @author: 北京-宏哥 QQ交流群:707699217
8 Project:学习和使用appium自动化测试-toast提示
9 '''
10 # 3.导入模块
11 from appium import webdriver
12 from selenium.common.exceptions import NoSuchElementException
13 from selenium.webdriver.support.ui import WebDriverWait
14 from selenium.webdriver.support import expected_conditions as EC
15
16 desired_caps = {'platformName': 'Android',
17 'platforVersion': '5.1.1',
18 'automationName': 'Uiautomator2',
19 'deviceName': '127.0.0.1:62001',
20 'app': r'C:\Users\DELL\Downloads\kaoyanbang.apk',
21 'appPackage': 'com.tal.kaoyan',
22 'appActivity': 'com.tal.kaoyan.ui.activity.SplashActivity',
23 'noReset': 'True'}
24
25 def is_toast_exist(driver,text,timeout=30,poll_frequency=0.5):
26
27 '''is toast exist, return True or False
28
29 :Agrs:
30
31 - driver - 传driver
32
33 - text - 页面上看到的文本内容
34
35 - timeout - 最大超时时间,默认30s
36
37 - poll_frequency - 间隔查询时间,默认0.5s查询一次
38
39 :Usage:
40
41 is_toast_exist(driver, "看到的内容")
42
43 '''
44
45 try:
46
47 toast_loc = ("xpath", ".//*[contains(@text,'%s')]"%text)
48
49 WebDriverWait(driver, timeout, poll_frequency).until(EC.presence_of_element_located(toast_loc))
50
51 return True
52
53 except:
54
55 return False
56 if __name__ == "__main__":
57
58 driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
59 driver.implicitly_wait(9)
60 try:
61 driver.find_element_by_id("android:id/button2").click()
62 except NoSuchElementException:
63 print(1)
64 try:
65 driver.find_element_by_id('com.tal.kaoyan:id/tv_skip').click()
66 except NoSuchElementException:
67 print(2)
68 driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').clear()
69 driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').send_keys('bjhongge')
70
71 driver.find_element_by_id('com.tal.kaoyan:id/login_password_edittext').send_keys('1213213')
72 driver.find_element_by_id('com.tal.kaoyan:id/login_login_btn').click()
73
74 error_message = "用户名或密码错误,你还可以尝试3次"
75 limit_message = "验证失败次数过多,请15分钟后再试"
76
77 print is_toast_exist(driver, error_message)