📜  在 selenium 中混合隐式等待和显式等待 (1)

📅  最后修改于: 2023-12-03 14:51:10.433000             🧑  作者: Mango

在 Selenium 中混合隐式等待和显式等待

在使用 Selenium 进行自动化测试时,等待是一个非常重要的话题。因为某些操作可能需要等待页面元素加载完全,或者某个动作需要一定时间才能完成,否则会导致测试失败。Selenium 提供了两种等待方式:隐式等待和显式等待。

隐式等待

隐式等待是在执行每个 Selenium 命令时起作用,它让测试脚本等待指定的时间,如果指定时间内找到了页面元素,则立即执行下一步操作;如果在规定时间内未找到页面元素,则抛出 NoSuchElementException 异常。这个等待时间是全局的,即使启动了一个新的浏览器实例,它也是有效的。

设置隐式等待的方法是使用 driver.implicitly_wait(time_to_wait),其中 time_to_wait 是等待的时间,单位是秒。下面是一个例子:

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10)  # 等待10秒
driver.get("http://www.baidu.com")
input_element = driver.find_element_by_id("kw")
input_element.send_keys("Selenium")
search_button = driver.find_element_by_id("su")
search_button.click()
driver.quit()

在这个例子中,Selenium 会在网页加载完成后等待 10 秒,如果在这个时间内找到了 ID 为“kw”的输入框,就输入“Selenium”这个关键字,并点击搜索按钮。如果在规定时间内找不到这个元素,就会抛出 NoSuchElementException 异常,测试失败。

显式等待

显式等待与隐式等待不同,它是指定某个条件,一直等待直到满足条件后才执行下一步操作。比如,我们可以让 Selenium 等待直到某个元素可见、可点击等,或者等待某个 JavaScript 脚本的执行结果。

设置显式等待的方法是使用 WebDriverWait 类,它需要传入两个参数:等待对象和最长超时时间。等待对象是一个 ExpectedCondition 类型的函数,用来判断等待条件是否达成。而最长超时时间指的是最长等待时间,如果在这个时间内等待条件还没达成,就抛出 TimeoutException 异常。

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("http://www.baidu.com")

WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "kw"))
)

input_element = driver.find_element_by_id("kw")
input_element.send_keys("Selenium")

WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.ID, "su"))
)
search_button = driver.find_element_by_id("su")
search_button.click()

driver.quit()

在这个例子中,我们先让 Selenium 等待页面加载完成,等待 ID 为“kw”的输入框可见后,就输入“Selenium”这个关键字,然后等待 ID 为“su”的搜索按钮可点击,最后点击搜索按钮。如果超时时间为 10 秒,但是在这个时间内等待条件还没达成,就抛出 TimeoutException 异常,测试失败。

混合等待

在实际测试中,往往需要同时使用隐式等待和显式等待。隐式等待可以处理页面资源长时间等待问题,显式等待可以处理页面元素加载完成等待问题。下面是一个同时使用两种等待方式的例子:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.implicitly_wait(10)

driver.get("http://www.baidu.com")

try:
    search_input = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "kw"))
    )
    search_button = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.ID, "su"))
    )

    search_input.send_keys("Selenium")
    search_button.click()

finally:
    driver.quit()

在这个例子中,我们同时设置了 10 秒的隐式等待和 10 秒的显式等待。如果在 10 秒内找到了 ID 为“kw”的输入框和 ID 为“su”的搜索按钮,就输入“Selenium”并点击搜索按钮。如果在这个时间内等待条件还没达成,就会抛出 TimeoutException 异常,测试失败。

综上,混合使用隐式等待和显式等待可以让测试更加健壮,能够处理各种等待情况,提高测试脚本的稳定性。