赞
踩
为什么需要等待?
自动化测试脚本在运行时,由于网络原因、机器卡顿、页面元素呈现等原因,导致定位失败。定位失败导致元素无法操作,获取不到用于断言的内容。
最终在检查测试结果时就会出现很多因为这些原因而导致的测试失败,需要花大量精力来排查才能找到真正意义上的问题。
所以必须要使用等待。其实 Selenium 是有默认等待的,当你打开页面时默认会等待页面元素加载完毕才进行元素定位。但是页面加载完毕后产生变化的元素则无法产生等待。
导致页面产生变化的原因:
ajax 动态加载内容
JavaScript 某些动作改变 HTML 页面元素:比如增加、删除元素,隐藏与可见元素等
通常来说,我们经常会使用三种等待方式:
强制等待
隐式等待
显式等待(智能等待)
这不是 Selenium 中提供的等待,而是使用 Python 标准库 time
中的 sleep()
函数。
sleep(second)
函数,会将线程挂起。参数为挂起的秒数。
程序运行时遇到 sleep() 函数就会停止设置的秒数,然后再运行下一句代码。
相当于给后面的元素定位提供一定的缓冲时间。
- import time
-
- time.sleep(0.5) # => 等待0.5秒
-
- driver.find_element_by_id('test').click()
这种方式不适合大面积使用,这属于硬性等待,不管元素是否能够定位到, 都需要等待固定的时间。如果加得太多,会造成代码中挂起时间过长,脚本运行效率降低。
只有当隐式等待和显式等待同时失效时才能使用此方式。
- 现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
- 如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
- 可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
- 分享他们的经验,还会分享很多直播讲座和技术沙龙
- 可以免费学习!划重点!开源的!!!
- qq群号:691998057【暗号:csdn999】
隐式等待,之所以这样叫,是因为不像 sleep() 函数,要等哪里就要在哪里写上一句;它只需要在初始生成浏览器驱动的时候加上就行,后续每个 find_element 类型的语句都会等待。
Sets a sticky timeout to implicitly wait for an element to be found,or a command to complete. This method only needs to be called one time per session.
设置隐含的时间用于等待元素查找和命令执行。每个 session 只需要调用此方法一次。
– Selenium 源码对该方法的注释
implicitly_wait(second)
方法用于实现这种隐式等待,参数表示等待超时的秒数。比如设置为 30,表示每个 find_element 语句都会等待,最长等待 30s。30s 后如果 find_element 语句都没有返回找到的元素则会抛出超时异常。
- driver = webdriver.Chrome()
- driver.implicitly_wait(30) # => 超时30s
其实隐式等待已经作用于所有的 find_element 语句,为何还需要显式等待呢?
常见原因是某些情况下元素处于动态变化的过程,会导致查找失败。
比如点击菜单后菜单展开,鼠标悬停某元素后元素呈现:
显式等待的用法如下:
- from selenium.webdriver.common.by import By
- #引入WebDriverWait
- from selenium.webdriver.support.ui import WebDriverWait
- #引入expected_conditions类,并重命名为EC
- from selenium.webdriver.support import expected_conditions as EC
-
- #设置等待
- wait = WebDriverWait(driver, 10, 0.5)
- wait.until(EC.presence_of_element_located((By.ID, "kw"))) # => 这里的(By.ID, "kw")组成一个元组
定位器 locator,在 Selenium 中把定位方式(如 By.ID, By.NAME 等)和 定位语句构成的元组称为定位器。
上面的例子的含义为:根据设定的时间间隔检查当前页面 id 为 “kw” 的元素是否存在,元素存在才进行下一步,如果超过设置时间检测不到则抛异常。
说明:
显式等待需要用到两个类:
WebDriverWait 和 expected_conditions 中的条件类。WebDriverWait 用来执行等待过程,expected_conditions 中的类用来指定结束等待的条件。
先说 WebDriverWait:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
参数说明:
dirver:浏览器驱动
Timeout:最长超时时间,默认以秒为单位
poll_frequency:检测的间隔步长,默认为0.5s
ignored_exceptions:超时后的抛出的异常类型,默认抛出 NoSuchElementException
异常。
对 WebDriverWait 进行实例化后,需要调用 until 方法进行实际的等待:
until(method, message='')
参数说明:
method:接收一个函数或方法作为参数,用来作为等待的条件
message:等待失败后在抛出的异常中显示的异常信息
作为条件的 expected_conditions 类:
用于设置一些预期条件,比如元素是否加载出来、元素是否可见等等。
expected_conditions 中提供的各种条件:
条件 | 说明 |
---|---|
title_is | 判断当前页面的title是否精确等于预期 |
title_contains | 判断当前页面的title是否包含预期字符串 |
presence_of_element_located | 判断某个元素是否被加到了 DOM 树里,并不代表该元素一定可见; 常用的条件,用于判断一个元素是否能被 find_element 找到 |
visibility_of_element_located | 判断某个元素是否可见; 可见代表元素非隐藏,并且元素的宽和高都不等于0; 常用的条件,用于判断元素是否可见 |
visibility_of | 与 visibility_of_element_located 作用一致; 接收的参数是元素对象而非定位器 |
presence_of_all_elements_located | 判断是否至少有1个元素存在于DOM树中; 举个例子,如果页面上有n个元素的class都是’column-md-3’,那么只要有1个元素存在,这个方法就返回True |
text_to_be_present_in_element | 判断某个元素中的text是否包含了预期的字符串 |
text_to_be_present_in_element_value | 判断某个元素中的value属性是否包含了预期的字符串 |
frame_to_be_available_and_switch_to_it | 判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False |
invisibility_of_element_located | 判断某个元素中是否不存在于DOM树或不可见 |
element_to_be_clickable | 判断某个元素中是否可见并且是enable的,这样的话才叫clickable |
staleness_of | 等某个元素从DOM树中移除,注意,这个方法也是返回True或False |
element_to_be_selected | 判断某个元素是否被选中了,一般用在下拉列表 |
element_selection_state_to_be | 判断某个元素的选中状态是否符合预期 |
element_located_selection_state_to_be | 跟上面的方法作用一样,只是上面的方法传入定位到的element,而这个方法传入定位器 |
alert_is_present | 判断页面上是否存在alert |
下面是配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!
最后: 可以在公众号:程序员小濠 ! 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。
如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。