1. 程式人生 > >selenium-webdriver中的顯式等待與隱式等待

selenium-webdriver中的顯式等待與隱式等待

在selenium-webdriver中等待的方式簡單可以概括為三種:
1 匯入time包,呼叫time.sleep()的方法傳入時間,這種方式也叫強制等待,固定死等一個時間
2 隱式等待,直接呼叫implicitly_wait()方法,傳入等待時間,比如implicitly_wait(10),就代表最長等待10秒
3 顯式等待,匯入WebDriverWait和expected_conditions包,呼叫until()者until_not()方法

下面重點介紹後兩種方式


一. 隱式等待:表示在自動化實施過程中,為查詢頁面元素或者執行命令設定一個最長等待時間,如果在規定時間內也沒元素被找到或命令被執行完成,則執行下一步,否則繼續等待直到設定的最長等待時間截止

下面來看段程式碼:

from selenium import webdriver
import unittest, time
from selenium.common.exceptions import NoSuchElementException, TimeoutException
import traceback


class VisitSogouByChrome(unittest.TestCase):
def setUp(self):
    # 啟動Chrome瀏覽器
    self.driver = webdriver.Chrome(executable_path="D:\\chromedriver")

def test_implictWait(self):
    url = 'https://www.baidu.com/'
    self.driver.get(url)
    # 設定隱式等待時間為10秒
    self.driver.implicitly_wait(10)
    try:
        search = self.driver.find_element_by_id("kw")
        search.send_keys("毒")
        click = self.driver.find_element_by_id("su")
        click.click()
    except (NoSuchElementException, TimeoutException):
        traceback.print_exc()

def tearDown(self):
    # 退出谷歌瀏覽器
    self.driver.quit()

這段程式碼基本就是完成開啟百度搜索頁,搜尋毒的操作。可以看到隱式等待就是呼叫implicitly_wait()的方法就可以了。
隱式等待的好處是不用像強制等待(time.sleep(n))的方法一樣死等固定時間n秒,可以在一定程度上提升測試用例的執行效率。但是這種方法也有一定弊端,就是程式將會一直等待到整個頁面載入完成,也就是說瀏覽器視窗標籤欄不再出現小圈圈,才會繼續執行下一步,比如某些時候頁面元素已經加再好了,但是某個js檔案等待資源慢了點,此時程式仍然會等待頁面全部載入完成才會執行下一步,這樣加長了測試用例的執行時間。

注意:隱式等待時間只需要設定一次,然後他將在driver整個生命週期都起作用


二. 顯式等待:通過selenium.webdriver.suppert.ui模組提供的WebDriverWait類,再結合該類的until()和until_not()的方法,並自定義好等待時間,根據判斷條件進行靈活等待。顯式等待比隱式等待更節約執行時間,因此更推薦使用顯式等待方式判斷頁面元素是否存在

WebDriverWait類解析:WebDriverWait類構造方法:
init(self, driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
引數解釋:
driver:WebDriver例項物件(IE,Firefox, Chrome等)
timeout: 最長等待時間,單位微妙
poll_frequency: 呼叫評率,也就是timeout時間段內,每隔poll_frequency時間執行一次判斷條件,預設0.5s
ignored_exceptions: 執行過程中忽略的異常物件,預設只忽略TimeoutException異常類

WebDriverWait類提供方法:

(1)until(method, message='')
在規定時間內,每隔一段時間呼叫一下method方法,至到期返回值不為False,如果超時丟擲帶有message的TimeoutException異常資訊
(1)until_not(method, message='')
與until()方法相反,表示在規定時間內,每隔一段時間呼叫一下method方法,至到期返回值為False,如果超時丟擲帶有message的TimeoutException異常資訊

下面這段程式碼是利用顯式等待判斷元素是否存在

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
def is_element_exsist2(driver, locator):
'''
結合WebDriverWait和expected_conditions判斷元素是否存在,
每間隔1秒判斷一次,30s超時,存在返回True,不存返回False
:param locator: locator為元組型別,如("id", "yoyo")
:return: bool值,True or False
'''
try:
    WebDriverWait(driver, 30, 1).until(EC.presence_of_element_located(locator))
    return True
except:
    return False
if __name__ == '__main__':
    loc1 = ("id", "kw")  # 元素1
    print(is_element_exsist2(driver, loc1))

顯式等待期望場景

  • presence_of_element_located(locator)判斷某個元素是否出現在DOM中,不一定可見,只要存在返回該頁面元素物件使用方法: wait.until(EC.presence_of_element_located((By.ID, "kw")))
  • alert_is_present()判斷頁面是否出現alert框,顯示等待中使用方法:
    wait = WebDriverWait(driver, 10)
    # 列印一下彈框資訊
    wait.until(EC.alert_is_present()).text
  • element_to_be_clickable(locator):判斷某元素是否可見並能點選,使用方法: wait.until(EC.element_to_be_clickable((By.ID, "kw")))
  • element_to_be_selected(locator):期望某個元素處於選中狀態,引數為一個WebDrover例項物件,使用方法:wait.until(EC.element_to_be_selected((By.ID, "kw")))
  • title_is(title_text):判斷頁面title內容是否與傳入的title_text內容完全匹配,是返回Ture,否返回False,使用方法:wait.until(EC.title_is(u"百度一下"))

以上只是簡單列舉了一下常用的一些方法,如果有其他需要可以閱讀官方文