WEB⾃动化_等待机制

148 阅读5分钟

1.强制等待(sleep)

定义:设定⼀个固定的等待时⻓,代码运⾏到此处,会强⾏进⾏等待指定的时间。

缺点:不能准确把握需要等待的时间

1.有时操作还未完成,等待就结束了,导致报错;

2.有时操作已经完成了,但等待时间还没有到,浪费时间;

3.如果在⽤例中⼤量使⽤,会浪费不必要的等待时间,影响测试⽤例的执⾏效率。

优点:使⽤简单,可以在调试时使⽤。

示例:

# 强⾏等待 10s

sleep(10)

2.隐式等待(implicitly_wait)

定义:设定⼀个固定的等待时间,对整个⽣命周期的元素都起作⽤,每⼀个元素都会等待加载完全,直到超过设定****的等待时间。

缺点:使⽤隐式等待,程序会⼀直等待整个⻚⾯加载完成,才会执⾏下⼀步操作;

优点:隐性等待对整个driver的周期都起作⽤,所以只要设置⼀次即可。

警告: **不要混合使⽤隐式和显式等待 。**这样做会导致不可预测的等待时间。例如,将隐式等待设置为10秒,将显式等待设置为15秒,可能会导致在20秒后发⽣超时。

1、# 隐式等待设定时⻓为5s

driver.implicitly_wait(5)

driver.get('www.baidu.com')

2、# 隐式等待所有元素加载完成,直到超过设定的最⻓时间

driver.find_element_by_id("element_id").click()

3.显式等待

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

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

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

1)WebDriverWait:

WebDriverWait(driver, timeout=30, poll_frequency=0.5, ignored_exceptions=None)

# 参数含义:

driver:浏览器驱动

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

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

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

NoSuchElementExeception异常

2)until()和until_not():

WebDriverWait ⼀般是配合until() 或 until_not()⽅法,就能够根据判断条件⽽灵活地等待了。主要的意思就是:程序每隔xx秒看⼀眼,如果条件成⽴了,则执⾏下⼀步;否则继续等待,直到超过设置的最⻓时间,然后抛出TimeoutException 异常。

1、until():

element = WebDriverWait(driver, 10).until(EC.presence_of_element_located

((By.XPATH, "//input[@id='txtUName']")))

2、until_not():

element = WebDriverWait(driver, 10).until_not(EC.presence_of_element_located

((By.XPATH, "//input[@id='11txtUName']")))

3)expected_conditions搭配显示等待使⽤:

官⽅⽂档链接:www.selenium.dev/selenium/do…

port/selenium.webdriver.support.expected_conditions.html?highlight=expected

注意:参数:locator (定位器:定位元素的⽅法)和 element(元素:元素本身)的⽤法

from selenium.webdriver.support import expected_conditions as ec

locator:

ec.presence_of_element_located((By.ID,'kw'))

element:

ec.visibility_of(driver.find_element(By.ID,'su'))

4)通过⻚⾯标题来判断:

1、title_is (title):判断当前⻚⾯的title是否完全等于(==)预期字符串,返回布尔值

# 元素等待直到标题出现"XXX"

WebDriverWait(driver,3).until(EC.title_is('XXX'))

sleep(5)

2、title_contains (title):判断当前⻚⾯的title是否包含预期字符串,返回布尔值

# 元素等待直到标题包含"读书屋"

WebDriverWait(driver, 3).until(EC.title_contains('读书屋'))

5)通过元素是否可⻅来判断:

通常在⽹⻚中并不是所有元素都是可⻅的,也有的是初始化时不可⻅,加载完成时则状态⼜变为可⻅,所以在元素等待中以下这些⽅式是经常被⽤到的。

1、presence_of_element_located (locator):判断某个元素是否被加到了dom树⾥,并不代表该元素⼀定可⻅

# 元素等待直到能定位到元素,这⾥是定位到搜索输⼊框

# 这⾥定位时不关⼼元素是否可⻅,只要是加载到DOM中能定位到即可

el = WebDriverWait(driver, 3).until(EC.presence_of_element_located

((By.XPATH, "//input[@id='txtUName']")))

2、visibility_of_element_located (locator):判断某个元素是否可⻅. 可⻅代表元素⾮隐藏,并且元素的宽和⾼都不等于0

# 元素等待直到能定位到可⻅的元素,⽐如这⾥定位到搜索按钮

# 和上⾯不同,这⾥等待的元素除加载DOM中,也必须可⻅

el = WebDriverWait(driver, 3).until(EC.visibility_of_element_located

((By.XPATH, "//input[@id='txtPassword']")))

注: presence_of_element_located和visibility_of_element_located,是显示等待中最常⽤的判断条件,2者之间的区别就是元素是否可⻅。

3、visibility_of (element):基本和上⾯⽅法效果⼀致,判断元素将会加载到⻚⾯DOM中,并可⻅

# 元素等待直到能定位到可⻅的元素,⽐如这⾥定位到搜索框

# 这个⽅法和上⾯ `visibility_of_element_located` 使⽤类似

el = WebDriverWait(driver, 3).until(EC.visibility_of(driver.find_element

(By.XPATH,

"//input[@id='btnLogin']")))

6)通过等待的元素包含的内容来判断:

text_to_be_present_in_element (locator, text_):判断某个元素中的text是否 包含 了预期的字符串

# 元素等待直到定位到指定的元素,并且元素中存在某text⽂本

WebDriverWait(driver, 3).until(EC.text_to_be_present_in_element(By.XPATH, "//b[text()='已收藏']"), '已收藏')

7)针对下拉框类型的等待,还有可点击的组件,如超链接:

element_to_be_clickable (locator):判断某个元素中是否可⻅并且是enable的,这样的话才叫clickable

# 元素等待直到元素被加载,为可⻅状态,并且是可点击的状态,才会结束等待

el = WebDriverWait(driver,3).until(ECS.element_to_be_clickable((By.LINK_TEXT,"登录")))

8)其他特殊判断:

1、alert_is_present ():判断⻚⾯上是否存在alert

# 元素等待直到⻚⾯加载出现 `alert`,出现⾃⼰切换过去并将提示内容返回

WebDriverWait(driver, 3).until(ECS.alert_is_present())

2、staleness_of (element):等某个元素从dom树中移除,注意,这个⽅法也是返回True或False

# 其他都是等待加载元素并操作,这种是等待元素被从Dom中移除时,才会触发结束等待

WebDriverWait(driver,3).until(ECS.staleness_of(driver.find_element(By.LINK_TEXT,'登录')))

3、frame_to_be_available_and_switch_to_it (locator):判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False

# 这种是⻚⾯有多个Frame时,等待⻚⾯加载直到 `frame1` 可以切换进去,这时就会⾃动切换到 `frame1` ,然后结束等待

WebDriverWait(driver,3).until(ECS.frame_to_be_available_and_switch_to_it

((By.XPATH, '//div[@id="another"]/iframe')))