web自动化测试页面等待

 

Waits 等待


 

WebDriver因为是异步触发元素或事件,有些时候脚本可能是间接性的,也有可能是断断续续的;又加浏览器和WebDriver脚本之间的存在竞争条件问题,因此我们需要引入等待包,让脚本运行不会出现阻塞或失败

 

使用等待时,我们需要引入等待包:

ui和wait里面都有WebDriverWait类,目前两种引包使用都没问题的;区别的话就是:ui模块里面引入的类就是wait下的WebDriverWait类 


from selenium.webdriver.support.ui import WebDriverWait


from selenium.webdriver.support.wait import WebDriverWait


三大等待之:显式等待

显式等待部分源码简介:


class WebDriverWait(object):
    def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, 
        self._driver = driver
        self._timeout = timeout
        self._poll = poll_frequency
        # avoid the divide by zero
        if self._poll == 0:
            self._poll = POLL_FREQUENCY
        exceptions = list(IGNORED_EXCEPTIONS)
        if ignored_exceptions is not None:
            try:
                exceptions.extend(iter(ignored_exceptions))
            except TypeError:  # ignored_exceptions is not iterable
                exceptions.append(ignored_exceptions)
        self._ignored_exceptions = tuple(exceptions)

    ...... # 省略的源码

    def until(self, method, message=''):
        """Calls the method provided with the driver as an argument until the \
        return value is not False."""
        screen = None
        stacktrace = None

        end_time = time.time() + self._timeout
        while True:
            try:
                value = method(self._driver)
                if value:
                    return value
            except self._ignored_exceptions as exc:
                screen = getattr(exc, 'screen', None)
                stacktrace = getattr(exc, 'stacktrace', None)
            time.sleep(self._poll)
            if time.time() > end_time:
                break
        raise TimeoutException(message, screen, stacktrace)

  • driver :Webdriver的实例(Ie、Firefox、Chrome)
  • timeout :设置超时时间
  • poll_frequency :休眠轮询时间,默认是0.5秒
  • ignored_exceptions :忽略特定的指定的异常

显式等待30秒,找不到元素就会抛出超时信息:


from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait

driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')


def waits_data(d):
    return d.find_element_by_xpath("//a[contains(text(),'高级搜索')]")


WebDriverWait(driver, 30).until(waits_data)


F:\virtualEnvironment\venv\Scripts\python.exe F:/git/AuomationTest/AuomationTestProject/webTestAuomation/selenium_waits.py
Traceback (most recent call last):
  File "F:/git/AuomationTest/AuomationTestProject/webTestAuomation/selenium_waits.py", line 19, in <module>
    WebDriverWait(driver, 30).until(waits_data)
  File "F:\virtualEnvironment\venv\lib\site-packages\selenium\webdriver\support\wait.py", line 80, in until
    raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 

您也可以把函数换成匿名函数,但是运行的结果是和上面一致的:


WebDriverWait(driver, 30).until(lambda p: p.find_element_by_xpath("//a[contains(text(),'高级搜索')]"))

WebDriverWait(driver, 30)中的until()方法是可以放判定条件的,满足条件后就不再等待了,until_not()方法是判定不满足条件的,也就是不满足这个条件就不再等待了。

WebDriver也提供了一个期望条件模块 expected_conditions:


from selenium.webdriver.support import expected_conditions

判断元素是否可见,可见指的是元素非隐藏:


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

driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')

WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.XPATH, "//a[contains(text(),'高级搜索')]")))

 

  • alert is present:判断页面上是否存在alert
  • title contains:判断当前页面的title是否包含预期字符串
  • title is:判断当前页面的title是否等于预期
  • frame_to_be_available_and_switch_to_it:检查frame表单是否可切进去。如果可以切进去,就切换到指定的frame框中。

更多的判定条件点击此处进行访问学习

WebDriverWait中忽略异常:

ignored_exceptions传入异常名称,可传多个异常名称,多个时以列表存储即可,异常最好捕获selenium.common.exceptions报出来的,基于BaseException的异常貌忽略不成功


# 捕获单个异常

WebDriverWait(driver, 5, ignored_exceptions='NoSuchElementException').until(EC.visibility_of_element_located((By.XPATH,"//a[contains(text(),'高级搜索')]")))

# 捕获多个异常

WebDriverWait(driver, 5, ignored_exceptions=['TimeoutException', 'NoSuchElementException']).until(EC.visibility_of_element_located((By.XPATH, "//a[contains(text(),'高级搜索')]")))



三大等待之:隐式等待

WebDriver在尝试查找任何元素时会轮询DOM一定时间。当网页上的某些元素无法立即使用且需要一些时间来加载时,需要了隐式等待,默认情况下隐式等待内元素是禁止出现的

注意:请勿混合使用隐式和显式等待,可能导致无法预测等待时间


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

driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get('https://www.baidu.com/')
driver.find_element_by_xpath("//a[contains(text(),'高级搜索')]")

 设置了driver.implicitly_wait(10)等待10秒,超过10秒等不到就抛异常:


F:\virtualEnvironment\venv\Scripts\python.exe F:/git/AuomationTest/AuomationTestProject/webTestAuomation/selenium_waits.py
Traceback (most recent call last):
  File "F:/git/AuomationTest/AuomationTestProject/webTestAuomation/selenium_waits.py", line 27, in <module>
    driver.find_element_by_xpath("//a[contains(text(),'高级搜索')]")
  File "F:\virtualEnvironment\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 394, in find_element_by_xpath
    return self.find_element(by=By.XPATH, value=xpath)
  File "F:\virtualEnvironment\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
    'value': value})['value']
  File "F:\virtualEnvironment\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "F:\virtualEnvironment\venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//a[contains(text(),'高级搜索')]"}
  (Session info: chrome=89.0.4389.72)



三大等待之:强制等待

导入time包,引入seep方法来强制等待,有些时候的页面加载的慢,可以使用这个强制睡眠1-2秒,能保证脚本运行的稳定性


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

driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
time.sleep(30)
driver.find_element_by_xpath("//a[contains(text(),'高级搜索')]")

time.seep(10)设置了10秒,超过时间没找到就抛异常:


F:\virtualEnvironment\venv\Scripts\python.exe F:/git/AuomationTest/AuomationTestProject/webTestAuomation/selenium_waits.py
Traceback (most recent call last):
  File "F:/git/AuomationTest/AuomationTestProject/webTestAuomation/selenium_waits.py", line 27, in <module>
    driver.find_element_by_xpath("//a[contains(text(),'高级搜索')]")
  File "F:\virtualEnvironment\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 394, in find_element_by_xpath
    return self.find_element(by=By.XPATH, value=xpath)
  File "F:\virtualEnvironment\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
    'value': value})['value']
  File "F:\virtualEnvironment\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "F:\virtualEnvironment\venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//a[contains(text(),'高级搜索')]"}
  (Session info: chrome=89.0.4389.72)

 

以上总结或许能帮助到你,或许帮助不到你,但还是希望能帮助到你,如有疑问、歧义,评论区留言会及时修正发布,谢谢!


未完,待续…
一直都在努力,希望您也是!

 

web自动化测试页面等待

 

 

 

 

 

 

 

 

 

 

上一篇:[Effective Java] Item 59 Avoid unnecessary use of checked exceptions


下一篇:[hypervisor]-AArch64 (hypervisor)Virtualization学习笔记