Selenium22-等待

等待

  • Selenium测试中为什么需要等待?
    • 在UI自动化测试中,有时会遇到运行环境不稳定、网络慢等情况,因为程序运行太快或者页面加载太慢而引起运行不稳定
  • 等待的设置是保证脚本稳定有效运行的一个非常重要的手段

三种等待方式

  • time.sleep(固定等待、强制等待) :等待固定的时间,是最简单但是最不推荐的方式。
  • implicitly_wait(隐式等待) :属于全局设置,等待直到元素出现后再操作。
  • WebDriverWait(显式等待) : 根据判断条件灵活的进行等待,语法最复杂。

强制等待

  • 设置等待最简单的方法就是强制等待time.sleep(xx):等待xx秒
    • 不管什么情况,让程序暂停运行一定时间,时间过后继续运行。
  • 优点: 语法简单,适合初学者
  • 缺点:不智能
    • 设置的时间太短,元素还没有加载出来,那照样会报错
    • 设置的时间太长,则会浪费时间

隐式等待

  • implicitly_wait(xx):设置等待的超时时间为xx秒
    • 示例:driver.implicitly_wait(10) # 等待超时时间设置为10秒
    • 等待直到元素加载完成为止,如果到了超时时间元素没有加载出,就抛出NoSuchElementException。
  • 优点:隐性等待的设置是全局性的
  • 缺点
    • 判断元素是否存在时耗时较多,代码运行效率低。
    • 不能实现复杂等待需求,比如弹出框出现、窗口出现、Frame出现等。
"""
	使用隐式等待完成多次灵活等待
	打开ECshop前台登录页
	输入第一组错误用户名和密码,点击立即登录
	等待跳转回登录页后,输入第二组错误的用户名和密码,点击立即登录
	等待跳转回登录页后,输入第三组错误的用户名和密码,点击立即登录
"""
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Firefox() # 启动浏览器
driver.implicitly_wait(10) # 设置隐式等待的超时时间为10秒
driver.get('http://localhost/upload/user.php') # 打开前台登录页
# 第一次错误
driver.find_element(By.NAME,"username").send_keys('adm232in')
driver.find_element(By.NAME,"password").send_keys('adm434in123')
driver.find_element(By.NAME,"submit").click()
# 第二次错误
driver.find_element(By.NAME,"username").send_keys('ad12min')
driver.find_element(By.NAME,"password").send_keys('adm2323in123')
driver.find_element(By.NAME,"submit").click()
# 第三次错误
driver.find_element(By.NAME,"username").send_keys('adm232in')
driver.find_element(By.NAME,"password").send_keys('adm232in123')
driver.find_element(By.NAME,"submit").click()
driver.quit()

显式等待

  • WebDriverWait类是由selenium提供的等待专用类,该类提供的until()和until_not()方法,可以根据判断条件灵活的进行等待
  • 显式等待的功能
    • 程序每隔几秒自动去检查一次,如果条件成立,则马上执行下一步,否则继续等待,如果直到超时设置的最长时间仍然不成立,就会抛出异常TimeoutException(超时异常)
  • 优点:等待条件丰富,单独控制,时间灵活,运行效率高
  • 缺点:语法复杂,难度大,学习成本高
    注意:
  • 隐式等待和显式等待可以同时用,但是注意等待的最长时间取两者之中的最大值
    • 示例:最多等待20秒。
    • driver.implicitly_wait(10)
    • WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))

显示等待步骤

  • 导入WebDriverWait
    from selenium.webdriver.support.wait import WebDriverWait
    
  • 封装WebDriverWait对象
    对象 = WebDriverWait(driver,timeout,poll_frequency,ignored_exceptions)
    driver 是传入的驱动程序对象实例
    timeout 是超时时间,等待的最长时间
    poll_frequency 调用until或until_not中的方法的间隔时间(默认是0.5秒)
    ignored_exceptions 忽略异常,是一个可迭代的异常类集合
    
  • 准备等待的自定义条件
  • 调用WebDriverWait的等待方式
  • WebDriverWait类的等待方法
    • until(method,message) 等待直到条件成立为止,常用
    • until_not(method,message) 等待直到条件不成立为止,不常用
    • method 是在等待期间,每隔一段时间调用这个传入的方法,直到返回值不为False
    • message 是如果超时,抛出TimeoutException,将message传入异常

expected_conditions模块

  • 是Selenium设计者专门为显式等待准备等待条件的一个模块,其中包含很多的等待条件
  • 可以对网页上元素是否存在,可点击等进行判断,一般用于断言或与WebDriverWait配合使用
  • 导入expected_conditions
    from selenium.webdriver.support import expected_conditions as EC
    # EC是自定义的别名,可以修改
    

expected_conditions模块用法

  • 网页标题相关等待条件
    • 判断当前页面的title是否精确等于预期,返回布尔值
    WebDriverWait(driver,10).until(EC.title_is("ECSHOP 管理中心"))
    
    • 判断当前页面的title是否包含预期字符串,返回布尔值
    WebDriverWait(driver,10).until(EC.title_contains("管理中心"))
    
  • URL相关等待条件有
    • 判断当前页面的url是否精确等于预期,返回布尔值
    WebDriverWait(driver,10).until(EC.url_to_be("https://www.baidu.com"))
    
    • 判断当前页面的url是否包含预期字符串,返回布尔值
    WebDriverWait(driver,10).until(EC.url_contains("login"))
    
    • 判断当前页面的url是否满足字符串正则表达式匹配,返回布尔值
    WebDriverWait(driver,10).until(EC.url_matches(".+login.+"))
    
    • 判断当前页面的url是否变化(不等于参数值就是变化),返回布尔值
    WebDriverWait(driver,10).until(EC.url_changes("https://www.baidu.com"))
    
  • 元素存在相关等待条件
    • 判断某个元素是否存在于网页源代码里,传参为元组,只要有一个元素出现,返回该元素对象
    WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"keyword")))
    
    • 判断多个元素是否存在于网页源代码里,传参为元组,在设置的等待时间内元素出现则条件成立并返回元素对象列表
    WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.NAME,"imageField")))
    
  • 一个元素可见相关等待条件
    • 判断某个元素是否可见(非隐藏的且宽和高都不为0),传参为元组,只要有一个元素出现,如果满足,返回该元素对象
    WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,"keyword")))
    
    • 判断某个元素是否不可见或不存在于网页源代码里,传参为元组,只要有一个元素出现,如果满足,返回True
    WebDriverWait(driver,10).until(EC.invisibility_of_element_located((By.ID,"keyword"))
    
  • 多个元素可见相关等待条件
    • 判断多个元素都出现且都可见(非隐藏的且宽和高都不为0),传参为元组,如果满足,返回元素对象的列表
    WebDriverWait(driver,10).until(EC.visibility_of_all_elements_located((By.CLASS_NAME,"kuaizhao")))
    
    • 判断多个元素都出现且至少有一个元素可见(非隐藏且宽和高都不为0),传参为元组,如果满足,返回元素对象的列表
    WebDriverWait(driver,10).until(EC.visibility_of_any_elements_located((By.CLASS_NAME,"kuaizhao")))
    
  • 元素内容相关等待条件有
    • 判断元素的文本里包含指定文本,返回布尔值
    WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.NAME,"tj_settingicon"),"设置"))
    
  • 判断元素的value属性值包含指定文本,返回布尔值
    WebDriverWait(driver,10).until(EC.text_to_be_present_in_element_value((By.ID,"su"),"百度"))
    
  • 元素控件状态相关等待条件
    • 判断某个元素可见并且是可点击的,返回这个元素,否则返回False
    WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.ID,"su")))
    
    • 判断某个元素被选中,一般用在下拉列表的选项、单选按钮、复选框
    WebDriverWait(driver,10).until(EC.element_located_to_be_selected((By.xpath,'//input[@type="checkbox"]')))
    
    • 判断某个元素是否被选中(True已被选中,False未选中)
    WebDriverWait(driver,10).until(EC.element_located_selection_state_to_be((By.NAME,'remember')),False)
    
  • Frame和Alert相关等待条件
    • 判断该Frame可以切换进去,如果可以的话,返回True并且切换进入Frame
    WebDriverWait(driver,10,).until(EC.frame_to_be_available_and_switch_to_it(By.xpath,'//iframe'))
    
    • 判断页面上存在消息框,如果有就切换到Alert并返回Alert对象
    WebDriverWait(driver,10).until(EC.alert_is_present())
    
  • Window相关等待条件
    • 判断浏览器窗口总数量等于某个值,返回布尔值
    WebDriverWait(driver,10,).until(EC.number_of_windows_to_be(2))
    
    • 判断新窗口被打开,期望打开一个新窗口并增加窗口句柄的数量。
    whs=driver.window_handles
    
    • 此处是某些可能出现新窗口的操作步骤,返回布尔值
    WebDriverWait(driver,10).until(EC.new_window_is_opened(whs))
    

练习显式等待




posted @   暄总-tester  阅读(101)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示