webdriver有两种等待方式:显式等待和隐式等待
因为现在大部分的web应用程序会使用AJAX技术。AJAX技术简单来说就是异步JavaScript和xml,是一种用户创建快速动态网页的技术,AJAX可以使网页实现异步更新,也就是可以不重新加载整个网页的情况下,对网页部分进行更新。
也就是加载网页的时候,页面的元素可能并不是同时被加载,这就对页面元素的定位产生了一定的困难。有可能在定位元素的过程中,由于某个需要定位的元素没有及时加载出来,可能会报ElementNotVisibleException这种情况,会极大降低自动化脚本的稳定性,所以我们可以通过设置等待的方式,来改善这种情况。
一、显式等待
显式等待有两种:一种是强制等待:通过线程等待函数,让自动化测试做一定时间的等待,Thread.sleep(1000);
使用此方法会出现两种不能避免的情况:1.若设置的时间较短,仍不能解决上述问题;2.若设置时间较长,会花费大量的等待时间。我们很难去确定等待时间的长度,因为加载时间的长度会受到外部环境的影响,比如:网络情况,应用的大小,主机的配置情况,主机的内存和CPU的消耗情况。
二是 使webdriver等待某个条件成立(界面某元素出现或者某可点击等条件)时,继续执行后续的操作,否则时间达到最大限值之后就抛出异常。采用WebDriverWait类 + ExceptedConditions接口
笔者比较推荐的方式就是这种方式
1 new WebDriverWait(driver, 10).until(ExpectedConditions
2 .presenceOfElementLocated(By.tagName("xxx")));
ExpectedConditions类有很多方法,下面列出一些常用的方法
方法 | 说明 |
titleIs(String) | 标题是不是“xxxx” |
titleContains(String) | 标题是不是包含“XXX” |
presenceOfElementLocated(By) | 判断该元素是否被加载在DOM中,并不代表该元素一定可见 |
visibilityOfElementLocated(By) | 判断元素是否可见(非隐藏,并且元素的宽和高都不等以0) |
visibilityOf(WebElement) | 判断元素(定位后)是否可见 |
presenceOfAllElementsLocatedBy(By) | 只要存在一个就是true |
textToBePresentInElementLocated(By, String) | 元素中的text是否包含预期的字符串 |
textToBePresentInElementValue(By, String) | 元素的value属性中是否包含预期的字符串 |
frameToBeAvailableAndSwitchToIt(By) | 判断该表单是否可以切过去,可以就切过去并返回true,否则返回false |
invisibilityOfElementLocated(By) | 判断某个元素是否不存在于DOM树或不可见 |
elementToBeClickable(By) | 判断元素是否可见并且是可以点击的 |
stalenessOf(WebElement) | 等到一个元素从DOM树中移除 |
elementToBeSelected(WebElement) | 判断某个元素是否被选中,一般用在下拉列表 |
elementSelectionStateToBe(By, boolean) | 判断某个元素的选中状态是否符合预期 |
elementSelectionStateToBe(WebElement, boolean) | 与上一个方法一样,只是该方法参数为定位后的元素,上一个方法接收的参数为定位判断某个元素(已定位)的选中状态是否符合预期 |
alertIsPresent() | 判断页面中是否存在alert |
二、隐式等待
相当于设置全局的等待,在定位元素时,对所有元素设置超时时间。
隐式等待使得WebDriver在查找一个Element或者Element数组时,如果一直查找不到,每隔一段特定的时间就会轮询一次DOM。
注:默认设置超时时间为0,一旦设置,这个隐式等待会在WebDriver对象实例的整个生命周期起作用。
隐式等待是通过一定的时长等待页面上某个元素加载完成。如果超过了设置的时长元素还没有被加载出来,则抛出NoSuchElementException异常。
1 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
代码中设置等待时间为10秒。首先这个10秒并非是一个固定的等待时间,它并不会影响脚本的执行速度。其次,它并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;如果元素定位不到,则它将会以轮询的方式不断地判断元素是否被定位到。假设,第5秒等位到元素,就继续执行;但是如果超出设置的这个10秒,那就直接抛出异常