Selenium中的显性等待WebDriverWait

07-19 1259阅读

前言

        在Selenium自动化测试中,显性等待是一项关键技术,它可以解决页面元素加载不稳定、异步加载以及网络延迟等问题。本文将深入研究Selenium中显性等待的深度使用,包括等待条件的种类、使用方式、以及一些实用的技巧。

Selenium中的显性等待WebDriverWait
(图片来源网络,侵删)

为什么需要显性等待?

        在Web应用程序中,元素不是一开始就存在于DOM中的,有时候需要等待一段时间直到它们出现。显性等待的目的是等待页面元素达到期望的状态,然后再继续执行后续的测试步骤。

显示等待的原理

        显示等待(WebDriverWait)配合该类的until()和until_not()方法,就能够根据判断条件而进行灵活地等待了.它主要的意思就是:程序每隔x秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException异常

显示等待的前提设置

显示等待需要用到两个类:WebDriverWait和expected_conditions两个类

WebDriverWait:指定轮询间隔、超时时间等

expected_conditions:指定了很多条件函数(也可以自定义条件函数)

需要导入:

 from selenium.webdriver.support.wait import WebDriverWait
 from selenium.webdriver.support import expected_conditions as ec # 用别名的方式,方便应用,简化引用名称
WebDriverWait里面包含了几种参数:
 WebDriverWait(driver, timeout=30, poll_frequency=0.5, ignored_exceptions=None)

driver:实例化的浏览器对象

timeout:最长超时时间,默认以秒为单位

poll_frequency:轮询的间隔时间,默认为0.5s

ignored_exceptions:忽略等待时出现的特定类型的异常,默认忽略

显示等待的常用条件设置

显示等待(WebDriverWait)结合expected_conditions提供的方法进行等待的条件设置。

1.until()和until_not()

until():

 element = WebDriverWait(driver, 10).until(ec.presence_of_element_located
                                               ((By.ID, "my_element_id")))

until_not():

 element = WebDriverWait(driver, 10).until_not(ec.presence_of_element_located
                                                   ((By.ID, "my_element_id")))
2.通过页面标题来判断

title_is():

判断当前页面的title是否完全等于(==)预期字符串,返回布尔值

 WebDriverWait(driver,10).until(ec.title_is('titile_element'))

title_contains():

判断当前页面的title是否包含预期字符串,返回布尔值

 WebDriverWait(driver, 10).until(ec.title_contains('titile_element'))
3.通过元素是否可见来判断

presence_of_element_located():

判断某个元素是否被加到了dom树里,并不代表该元素一定可见

 WebDriverWait(driver, 3).until(ec.presence_of_element_located
                                         ((By.ID, "my_element_id")))

visibility_of_element_located():

判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于0

 WebDriverWait(driver, 3).until(ec.visibility_of_element_located
                                         ((By.ID, "my_element_id")))

visibility_of():

基本和上面方法效果一致,判断元素将会加载到页面DOM中,并可见

 el = WebDriverWait(driver, 3).until(ec.visibility_of(driver.find_element
                                                          (By.ID, "my_element_id")))

presence_of_all_elements_located():

判断是否至少有1个元素存在于dom树中。

 WebDriverWait(driver, 3).until(ec.presence_of_all_elements_located((By.ID, "my_element_id")))

visibility_of_any_elements_located():

判断是否至少有1个元素存在于dom树中,并且可见。

 WebDriverWait(driver, 3).until(ec.visibility_of_any_elements_located((By.ID, "my_element_id")))

invisibility_of_element_located():

判断某个元素中是否不存在于dom树或不可见

 WebDriverWait(driver, 3).until \
         (ec.invisibility_of_element_located((By.ID, "my_element_id"))
4.通过等待的元素包含的内容来判断

text_to_be_present_in_element():

判断某个元素中的text是否 包含 了预期的字符串

 WebDriverWait(driver, 3).until(ec.text_to_be_present_in_element((By.ID, "my_element_id", 'elemenet_txt'))

text_to_be_present_in_element_value():

判断某个元素中的value属性是否 包含 了预期的字符串

 WebDriverWait(driver, 3).until(ec.text_to_be_present_in_element_value((By.ID, "my_element_id", 'elemenet_txt'))

等待的超时异常

如果超过指定的等待时间,而仍然没有找到期望的元素,将抛出TimeoutException。可以通过try和except块来处理这个异常。

 from selenium.common.exceptions import TimeoutException
 ​
 try:
     element = WebDriverWait(driver, 10).until(
         EC.presence_of_element_located((By.CSS_SELECTOR, ".my_selector"))
     )
 except TimeoutException:
     print("Element not found within 10 seconds.")

自定义等待条件

除了Selenium提供的内置等待条件外,你还可以自定义等待条件。这对于处理一些特殊情况非常有用。

 from selenium.webdriver.support.ui import WebDriverWait
 from selenium.webdriver.support import expected_conditions as ec
 from selenium.webdriver.common.by import By
 ​
 class custom_condition:
     def __init__(self, element_locator):
         self.element_locator = element_locator
 ​
     def __call__(self, driver):
         element = driver.find_element(self.element_locator)
         if element.get_attribute("data-custom-attribute") == "expected_value":
             return element
         else:
             return False
 ​
 element_locator = (By.XPATH, "//div[@id='custom_div']")
 element = WebDriverWait(driver, 10).until(custom_condition(element_locator))

等待的嵌套使用

有时候,页面的某个元素可能是动态加载的,需要等待元素加载完成后再等待它的子元素。

 parent_element_locator = (By.ID, "parent_element")
 child_element_locator = (By.CLASS_NAME, "child_element")
 ​
 parent_element = WebDriverWait(driver, 10).until(
     ec.presence_of_element_located(parent_element_locator)
 )
 ​
 child_element = WebDriverWait(parent_element, 10).until(
     ec.presence_of_element_located(child_element_locator)
 )

结语

显示等待是企业中常用的一种综合性的等待方式,能够解决的复杂场景也是多种多样的,那么我们今天就分享到这,下次再见👋🏻,更多测试技术支持 -- vi:lmx201125

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]