前言:
本文为在霍格沃兹测试开发学社中学习到的一些技术写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步~ 😘
添加等待的原因:避免页面未渲染完成后操作,导致的报错。
示例:
#演示代码中未添加任何等待from appium import webdriver
from appium.webdriver.common.appiumby import AppiumByclass TestXueQiu:def setup(self):# 创建一个字典desire_cap = {}# 平台desire_cap['platform'] = 'Android'#手机系统版本desire_cap['platformVersion']= '6.0'# 设备名desire_cap['deviceName'] = '127.0.0.1:7555'# app 包名desire_cap['appPackage'] = 'com.xueqiu.android'# app 页面名desire_cap['appActivity'] = '.common.MainActivity'desire_cap['noReset'] = 'true'#每次测试重置数据desire_cap['skipDeviceInitization']= 'true'#保证可以正常输入中文desire_cap['unicodeKeyBoard'] = 'true'desire_cap['resetKeyBoard'] = 'true'self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desire_cap)def teardown(self):# 回收sessionself.driver.quit()def test_api_demo(self):self.driver.find_element(AppiumBy.ID, "com.xueqiu.android:id/tv_search").click()self.driver.find_element(AppiumBy.ID, "com.xueqiu.android:id/search_input_text").send_keys("alibaba")self.driver.find_element(AppiumBy.ID,"com.xueqiu.android:id/code").click()
运行结果:运行报错,报错原因是未找到定位的元素
sleep()(不推荐)driver.impicitly_wait(TIMEOUT)WebDriverWait(self.drier,10).until(expected_conditions.visibility_of_element_located(LOCATOR))解决方案:在报错的元素操作之前添加等待
原理:强制等待,线程休眠一定时间
方式:time.sleep(3)
示例:
import time
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumByclass TestXueQiu:def setup(self):# 创建一个字典desire_cap = {}# 平台desire_cap['platform'] = 'Android'#手机系统版本desire_cap['platformVersion']= '6.0'# 设备名desire_cap['deviceName'] = '127.0.0.1:7555'# app 包名desire_cap['appPackage'] = 'com.xueqiu.android'# app 页面名desire_cap['appActivity'] = '.common.MainActivity'desire_cap['noReset'] = 'true'#每次测试重置数据desire_cap['skipDeviceInitization']= 'true'#保证可以正常输入中文desire_cap['unicodeKeyBoard'] = 'true'desire_cap['resetKeyBoard'] = 'true'self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desire_cap)def teardown(self):# 回收sessionself.driver.quit()def test_api_demo(self):time.sleep(3)self.driver.find_element(AppiumBy.ID, "com.xueqiu.android:id/tv_search").click()time.sleep(3)self.driver.find_element(AppiumBy.ID, "com.xueqiu.android:id/search_input_text").send_keys("alibaba")time.sleep(3)self.driver.find_element(AppiumBy.ID,"com.xueqiu.android:id/code").click()#添加直接等待,每一步操作前会强制等待3秒钟
问题:难以确定元素加载的具体等待时间。
解决方案:针对于寻找元素的这个动作,使用隐式等待添加配置:driver.implicitly_wait(seconds)
原理:隐式等待是一种全局的等待方式,设置一个等待时间,轮询查找(默认 0.5 秒)元素是否出现,如果没出现就抛出异常
示例:
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumByclass TestXueQiu:def setup(self):# 创建一个字典desire_cap = {}# 平台desire_cap['platform'] = 'Android'#手机系统版本desire_cap['platformVersion']= '6.0'# 设备名desire_cap['deviceName'] = '127.0.0.1:7555'# app 包名desire_cap['appPackage'] = 'com.xueqiu.android'# app 页面名desire_cap['appActivity'] = '.common.MainActivity'desire_cap['noReset'] = 'true'#每次测试重置数据desire_cap['skipDeviceInitization']= 'true'#保证可以正常输入中文desire_cap['unicodeKeyBoard'] = 'true'desire_cap['resetKeyBoard'] = 'true'self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desire_cap)#添加隐式等待:设置一个等待时间,轮询查找(默认0.5秒)元素是否出现,如果没出现就抛出异常self.driver.implicitly_wait(3)def teardown(self):# 回收sessionself.driver.quit()def test_api_demo(self):self.driver.find_element(AppiumBy.ID, "com.xueqiu.android:id/tv_search").click()self.driver.find_element(AppiumBy.ID, "com.xueqiu.android:id/search_input_text").send_keys("alibaba")self.driver.find_element(AppiumBy.ID,"com.xueqiu.android:id/code").click()#在setup中添加了隐式等待。
无法解决的问题:
原因:
解决方案:使用显式等待。
html文件是自上而下进行加载,并在加载过程完成解析与渲染。大致过程如下:
❗ 注意:html加载的过程是逐步完成的,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html 都解析完成之后再去构建和布局 render 树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。
由于html加载方式,所以过程中内容虽然会呈现在屏幕上,但元素的属性不一定全部被解析。如果此时我们使用元素属性去定位的话,可能会因为属性未被加载好而出现定位失败的情况。
隐式等待可以判断出元素已经出现在dom树中,但是无法盘判断元素属性是否被成功加载。如果使用隐式等待也会出现定位失败的情况。而显示等待可以等待动态加载的ajax元素,因此显示等待可以解决因元素属性未被加载而导致的定位失败。
方法说明: WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
参数说明:
方法说明:
until( method, message='') :当某元素出现或什么条件成立则继续执行
until_not(method, message='') :当mou元素消失或什么条件不成立则继续执行。
参数说明:
presence_of_element_located:判断元素是否被加载到dom树里,并不代表元素一定可被定位
用法:WebDriverWait().until(expected_conditions.presence_of_element_located(元素对象))
visibility_of_element_located:判断某个元素是否可见,可见代表元素非隐藏,并且元素的宽和高都不等于0.
用法:WebDriverWait().until(expected_conditions.visibility_of_element_located(locator))
element_to_be_clickable:判断每个元素是否可点击
用法:WebDriverWait().until(expected_conditions.element_to_be_clickable(locator))
……(其他方法可自行去了解)
示例1:
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWaitclass TestXueQiu:def setup(self):desired_caps = {}desired_caps['platformName'] = 'Android'desired_caps['platformVersion'] = '6.0'desired_caps['deviceName'] = '127.0.0.1:7555'desired_caps['appPackage'] = 'com.xueqiu.android'desired_caps['appActivity'] = '.view.WelcomeActivityAlias'desired_caps['noReset'] = 'true'self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)#使用隐式等待self.driver.implicitly_wait(10)def teardown(self):self.driver.quit()def test_xueqiu(self):"""1、打开 雪球 app2、点击搜索输入框3、像搜索框中输入“阿里巴巴”4、在搜索结果中选择“阿里巴巴”,然后进行点击5、获取这只上 阿里巴巴的股价,并判断这只股价的价格<2006、断言"""# 定位搜索框并进行点击self.driver.find_element(AppiumBy.ID, 'com.xueqiu.android:id/tv_search').click()# 搜索框输入“阿里巴巴”self.driver.find_element(AppiumBy.ID, 'com.xueqiu.android:id/search_input_text').send_keys("阿里巴巴")# 在搜索结果中选择“阿里巴巴”,并且点击self.driver.find_element(AppiumBy.XPATH,"//*[@resource-id='com.xueqiu.android:id/name' and @text='阿里巴巴']").click()# 获取当前股价#元组,元素定位方式和定位值cur_price_el=(AppiumBy.ID, 'com.xueqiu.android:id/current_price')#使用显示等待,用visibility_of_element_located去判断元素是否加载好WebDriverWait(self.driver,10).until(expected_conditions.visibility_of_element_located(cur_price_el))#直接使用cur_price_el。元组需要解包所以使用*cur_price_elcurrent_price = float(self.driver.find_element(*cur_price_el).text)# 断言assert current_price < 200
示例2:until中使用lambda表达式来进行查询元素
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWaitclass TestXueQiu:def setup(self):desired_caps = {}desired_caps['platformName'] = 'Android'desired_caps['platformVersion'] = '6.0'desired_caps['deviceName'] = '127.0.0.1:7555'desired_caps['appPackage'] = 'com.xueqiu.android'desired_caps['appActivity'] = '.view.WelcomeActivityAlias'desired_caps['noReset'] = 'true'self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)#使用隐式等待self.driver.implicitly_wait(10)def teardown(self):self.driver.quit()def test_xueqiu(self):"""1、打开 雪球 app2、点击搜索输入框3、像搜索框中输入“阿里巴巴”4、在搜索结果中选择“阿里巴巴”,然后进行点击5、获取这只上 阿里巴巴的股价,并判断这只股价的价格<2006、断言"""# 定位搜索框并进行点击self.driver.find_element(AppiumBy.ID, 'com.xueqiu.android:id/tv_search').click()# 搜索框输入“阿里巴巴”self.driver.find_element(AppiumBy.ID, 'com.xueqiu.android:id/search_input_text').send_keys("阿里巴巴")# 在搜索结果中选择“阿里巴巴”,并且点击self.driver.find_element(AppiumBy.XPATH,"//*[@resource-id='com.xueqiu.android:id/name' and @text='阿里巴巴']").click()# 获取当前股价cur_price_el=(AppiumBy.ID, 'com.xueqiu.android:id/current_price')#until中不使用expected_conditions类,使用lambda函数来进行判断WebDriverWait(self.driver,10).until(lambda x:x.find_element(*cur_price_el))current_price = float(self.driver.find_element(*cur_price_el).text)# 断言assert current_price < 200
文末说明:
接口测试中我们很容易混淆Session、cookie和token,你知道他们有什么区别吗?快来跟我一起看,一篇文章让你了解三者的区别。😎
⬇⬇⬇⬇⬇⬇⬇
👍👍👍:接口测试经典面试题:Session、cookie、token有什么区别?