目录
前言
web自动化测试,常常因为硬件配制,浏览器,网速等因素导致网页加载速度过慢,需要加入等时间。使用Selenium做自动化时,可以用到三种等待方式:线程等待(睡眠)、隐性等待,显性等待
提供自动化测试练手的网站:scho测试练手网站http://schotest.hunwei.top/
三种等待
一、线程等待
time.sleep()
此方法多用于线程延迟执行,线程挂起等场景,像自动化执行就是线程挂起场景:
让进程睡上几秒,等待元素加载成功,线程醒来后再操作页面元素。
形象展示其作的代码
import time
print("开始时间 : %s" % time.ctime())
time.sleep(5) #睡眠五秒
print("结束时间 : %s" % time.ctime())
参数是数字(整型,浮点型),以秒为单位
练手网站登录页面如下,账密编辑框都可以以name为定位,值分别是username、password
代码编辑如下
import time
from selenium import webdriver
#导入元素定位类型枚举
from selenium.webdriver.common.by import By
webdr = webdriver.Chrome() #Chrome没有带路径参数需要将chromedriver.exe跟本文件放在同一个目录下面
webdr.get(url='http://schotest.hunwei.top/')
# 等待一般加在这类位置,在渲染页面元素出现过程中。
print("开始时间 : %s" % time.ctime())
time.sleep(5) #睡眠五秒
print("结束时间 : %s" % time.ctime())
webdr.find_element(By.NAME, 'username').clear()
webdr.find_element(By.NAME, 'username').send_keys('admin')
webdr.find_element(By.NAME, 'password').clear()
webdr.find_element(By.NAME, 'password').send_keys('qwer1234')
webdr.find_element(By.XPATH, '//*[@id="app"]/div/form/button').click()
运行 成功登录到系统,规矩的等待了5秒
二、隐性等待
implicitly_wait()
隐性等待
webdr.implicitly_wait(5)
上行代码是1~5秒内等待页面加载完成,加载完成页面后,将停止等待(比如页面在第2秒加完成,就停止等待,后面3秒不再等待)执行下一步代码。
当然5秒页面没刷新成功,那也不再等待,也执行下一步代码,接着因找不到元素报错
隐性等待比起线程等待它更智能,更效率。隐性等待是webdriver自带的等待方式,很受大众喜爱。
案例代码如下:
import time
from selenium import webdriver
#导入元素定位类型枚举
from selenium.webdriver.common.by import By
webdr = webdriver.Chrome() #Chrome没有带路径参数需要将chromedriver.exe跟本文件放在同一个目录下面
webdr.get(url='http://schotest.hunwei.top/')
# 等待一般加在这类位置,在渲染页面元素出现过程中。
print("开始时间 : %s" % time.ctime())
webdr.implicitly_wait(10) #睡眠五秒
print("结束时间 : %s" % time.ctime())
webdr.find_element(By.NAME, 'username').clear()
webdr.find_element(By.NAME, 'username').send_keys('admin')
webdr.find_element(By.NAME, 'password').clear()
webdr.find_element(By.NAME, 'password').send_keys('qwer1234')
webdr.find_element(By.XPATH, '//*[@id="app"]/div/form/button').click()
像下图,因为网站很快,页面一秒都不想等待,运行的老快了
三、显性等待
隐性等待虽好,页面加载完成了,网站开发者说,我为了性能,要做很多异步加载的元素,页面加载完成,异步加载的元素还在加载中,自动化测试脚本 find_element 又找不元素了。
这时就看显性等待的了
WebDriverWait
案例代码
import time
from selenium import webdriver
#导入元素定位类型枚举
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
webdr = webdriver.Chrome() #Chrome没有带路径参数需要将chromedriver.exe跟本文件放在同一个目录下面
webdr.get(url='http://schotest.hunwei.top/')
# 等待一般加在这类位置,在渲染页面元素出现过程中。
print("开始时间 : %s" % time.ctime())
WebDriverWait(webdr, 30, 0.5).until(EC.visibility_of_element_located((By.NAME, 'username')))
print("结束时间 : %s" % time.ctime())
webdr.find_element(By.NAME, 'username').clear()
webdr.find_element(By.NAME, 'username').send_keys('admin')
webdr.find_element(By.NAME, 'password').clear()
webdr.find_element(By.NAME, 'password').send_keys('qwer1234')
webdr.find_element(By.XPATH, '//*[@id="app"]/div/form/button').click()
WebDriverWait(webdr, 30, 0.5).until(EC.visibility_of_element_located((By.NAME, 'username')))
显性等待这一行代码解析
WebDriverWait为第一部分
until为第二部分
第一部分: 传入webdriver对象,等待30s,每0.5s执行一下until里的代码
第二部分: EC是expected_conditions是Selenium的一个判断元素的模块,
visibility_of_element_located 表示判断元素(By.NAME, 'username')是否可见
这两部分组成的含义:等待30s,每0.5s检查一次指定元素是否可见,可见后,跳出等待,超过30s都指定元素没有出现,抛出TimeoutException异常。
显性等待能等待隐性等待处理不了的异步加载,所以在自动化使用中,频次出现是最高的。
执行
封装
在手撸自动化框架时,需要将一些常用的脚本先封装好,设计好既定的参数与返回值,上述三种等待是很好封装的。
个人喜好自然语言系列的自动化测试框架,
自然语言有的小伙伴认为它是关键字驱动,没数据驱动好(个人面试时经常遇到这种说法的面试官,也不是说他怎么的,但思想有点守旧,不开放),
关键字驱动与数据驱动结合开发框架不难的。容易上手、批量执行应该是框架两个小特性。
在这里我们可以将三种等待封装在一起,
一、参数设计
参数1、等待类型 wait_type:用来接收,等待,隐性等待,显性等待三种类型之一
参数2、 等待时间 secs:用来接收等待时间,单位是秒,默认3s
参数3、元素类型 type:接收元素定位顺类型,如:id, name, xpath等等,默认为空
参数4、元素定位器 location:接收定位器,如: username,password, //*[@id='su']等等,默认空、
参数5、浏览器对象 opr:接收webdriver.Chrome对象,默认为空
二、函数名设计
按照上面的设计,封闭函数名称如下
def waiting_for_element(wait_type, secs=3, type=None, location=None, opr:webdriver.Chrome=None):
疑问:为啥后面三个参数默认为空?带着疑问看下去,自行在代码中寻找答案。
三、封装代码设计
import time
from selenium import webdriver
#导入元素定位类型枚举
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
'''
定位类型字典设计
手撸框架可以节省很多if...else...代码
'''
LOCATION_TYPE = {
'id': By.ID,
'name': By.NAME,
'class': By.CLASS_NAME,
'tag': By.TAG_NAME,
'link': By.LINK_TEXT,
'plink': By.PARTIAL_LINK_TEXT,
'xpath': By.XPATH,
'css': By.CSS_SELECTOR
}
def waiting_for_element(wait_type, secs=3, type=None, location=None, opr:webdriver.Chrome=None):
if wait_type == '等待':
time.sleep(secs)
return True, '【等待】成功'
elif wait_type == '隐性等待':
opr.implicitly_wait(secs)
return True, '【隐性等待】成功'
elif wait_type == '显性等待':
if type is None or location is None or opr is None:
return False, '【显性等待】请填写所有参数'
try:
WebDriverWait(opr, secs, 0.5).until(EC.visibility_of_element_located((LOCATION_TYPE[str.lower(type)],location)))
except TimeoutException as e:
return False, '【显性等待】{}秒超时,元素[{}]=[{}]没有出现'.format(str(secs), type, location)
except Exception as e:
return False, '【显性等待】传参有误,请检查参数'
编写自动化测试脚本测试封装
webdr = webdriver.Chrome() #Chrome没有带路径参数需要将chromedriver.exe跟本文件放在同一个目录下面
webdr.get(url='http://schotest.hunwei.top/')
# 等待一般加在这类位置,在渲染页面元素出现过程中。
print("开始时间 : %s" % time.ctime())
#waiting_for_element('等待') #线程等待的调试
# waiting_for_element('隐性等待', 10, opr=webdr) #隐性等待的调试
print(waiting_for_element('显性等待', 10, type='id', location='username', opr=webdr)) #显性等待的调试,此处故意将type='id',引起它找不到id='username'的元素
print("结束时间 : %s" % time.ctime())
webdr.find_element(By.NAME, 'username').clear()
webdr.find_element(By.NAME, 'username').send_keys('admin')
webdr.find_element(By.NAME, 'password').clear()
webdr.find_element(By.NAME, 'password').send_keys('qwer1234')
webdr.find_element(By.XPATH, '//*[@id="app"]/div/form/button').click()
执行结果
本文到此告一段落
望大家多多点赞收藏
兄弟文有
新版selenium4.0 + Python使用详解https://mp.csdn.net/mp_blog/creation/editor/124637868
新版 Selenium4.0 与 谷歌、火狐、Edge浏览器的兼容性封装https://mp.csdn.net/mp_blog/creation/editor/126356747