在Selenium中使用等待机制:强制等待、隐式等待和显式等待
在自动化测试中,等待是一个非常重要的部分,因为它可以帮助确保测试脚本在执行操作前,页面元素已经加载完成或者变为可用。Selenium WebDriver 提供了多种等待机制,本文将详细介绍强制等待、隐式等待和显式等待,并给出相应的Java代码示例。
强制等待(Thread.sleep)
概述:
强制等待是通过暂停当前线程一段固定的时间来实现的。这种等待方式不依赖于任何条件,即使目标元素已经加载完成,线程也会继续等待直到指定时间结束。
优点:
- 简单直接,易于理解和使用。
缺点:
- 固定等待时间可能导致效率低下。
- 无法响应元素提前加载,导致不必要的等待。
- 不推荐在生产环境中使用,只适合调试阶段。
代码示例:
importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.chrome.ChromeDriver;publicclassForceWaitExample{publicstaticvoidmain(String[] args){WebDriver driver =newChromeDriver();
driver.get("http://xxx.com");// 强制等待5秒try{Thread.sleep(5000);}catch(InterruptedException e){
e.printStackTrace();}// 继续执行后续操作
driver.quit();}}
隐式等待(Implicit Wait)
概述:
隐式等待(Implicit Wait)是一种全局等待策略,它会在找不到元素时等待一段时间。如果在指定时间内元素仍未出现,WebDriver 会抛出
NoSuchElementException
。一旦设置,隐式等待将在整个WebDriver实例的生命周期内都有效。
简单点来理解,隐式等待是对所有的查找都起作用,比如,我在代码的第一行设置了隐式等待,那么后续出现的所有查找相关的代码(不管查找什么,只要和查找相关),就会依次等待。
- 一次设置,全局有效。
- 减少由于元素未加载完成而导致的
NoSuchElementException
。
缺点:
- 对于不同操作可能需要不同的等待时间,隐式等待无法满足这种需求。
- 会增加所有查找操作的时间,可能会导致测试运行时间增加。
代码示例:
importorg.openqa.selenium.By;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.chrome.ChromeDriver;importjava.util.concurrent.TimeUnit;publicclassImplicitWaitExample{publicstaticvoidmain(String[] args){WebDriver driver =newChromeDriver();// 设置隐式等待时间为10秒
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.get("http://xxxx.com");// 尝试查找元素,最多等待10s,找到就执行下面的,找不到就报错
driver.findElement(By.cssSelector("xxx")).click();//
driver.quit();}}
注意事项:
- 隐式等待会影响所有的
findElement
和findElements
方法。 - 如果在查找元素时,设置的隐式等待时间较长,可能会影响测试执行效率。
更详细的例子:
示例说明
假设我们需要在一个页面上依次查找几个元素,并且都能在隐式等待时间内找到。这几个查找操作将依次进行,且每个操作都会应用隐式等待。
importorg.openqa.selenium.By;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.chrome.ChromeDriver;importjava.util.concurrent.TimeUnit;publicclassImplicitWaitSequentialExample{publicstaticvoidmain(String[] args){WebDriver driver =newChromeDriver();// 设置隐式等待时间为10秒
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.get("http://xxx.com");// 第一次查找元素WebElement element1 = driver.findElement(By.cssSelector("#myElement1"));
element1.click();// 执行操作// 第二次查找元素WebElement element2 = driver.findElement(By.cssSelector("#myElement2"));
element2.sendKeys("Hello");// 执行操作// 修改隐式等待时间为5秒,后续的查找就是等待5s
driver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);// 第三次查找元素WebElement element3 = driver.findElement(By.cssSelector("#myElement3"));
element3.sendKeys("Hello");// 执行操作
driver.quit();}}
详细步骤
- 设置隐式等待:
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
这行代码设置了全局的隐式等待时间为10秒。 - 第一次查找元素:
WebElement element1 = driver.findElement(By.cssSelector("#myElement1"));
WebDriver开始查找id
为myElement1
的元素。如果元素不存在,WebDriver会在10秒内反复尝试查找,直到找到元素或超时。 - 执行操作:
element1.click();
一旦找到myElement1
,立即执行点击操作。 - 第二次查找元素:
WebElement element2 = driver.findElement(By.cssSelector("#myElement2"));
WebDriver开始查找id
为myElement2
的元素,同样会在10秒内反复尝试查找,直到找到元素或超时。 - 执行操作:
element2.sendKeys("Hello");
一旦找到myElement2
,立即执行发送文本操作。 - 修改等待时间
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
修改后续的等待时间为5s。 - 执行操作
WebElement element3 = driver.findElement(By.cssSelector("#myElement3"));
WebDriver开始查找id
为myElement2
的元素,这里就是 5 秒内反复尝试查找,直到找到元素或超时。
总结
在设置了隐式等待后,WebDriver会在每次查找元素时,依次应用隐式等待。每个查找操作都是独立的,当前查找操作完成后才会进行下一个查找操作。因此,对于多个查找操作,它们会一个执行完再执行另一个,确保每个操作都能在指定的隐式等待时间内找到相应的元素并执行后续操作。
显式等待(Explicit Wait)
概述:
显式等待是在指定条件满足之前,WebDriver会等待特定的时间。常用的条件包括元素是否可见、是否可点击等。显式等待是针对具体的操作单独设置的,更加灵活。
优点:
- 灵活,可以针对每个操作设置不同的等待条件和时间。
- 提高测试的稳定性,只有在条件满足时才继续执行后续操作。
缺点:
- 需要为每个操作单独编写等待逻辑,代码较为冗长。
代码示例:
importorg.openqa.selenium.By;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.chrome.ChromeDriver;importorg.openqa.selenium.support.ui.ExpectedConditions;importorg.openqa.selenium.support.ui.WebDriverWait;publicclassExplicitWaitExample{publicstaticvoidmain(String[] args){System.setProperty("webdriver.chrome.driver","/path/to/chromedriver");WebDriver driver =newChromeDriver();
driver.get("http://example.com");// 设置显式等待,最多等待10秒钟WebDriverWait wait =newWebDriverWait(driver,10);//级别是 s// 针对特定的条件进行等待,直到找到或超时WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("myElement")));// 继续执行后续操作
element.click();
driver.quit();}}
wait.until()方法会先执行条件,如果条件成立(即元素变为可点击状态),则继续执行后续的代码;如果条件不成立,则会一直等待,直到超过预期的时间(即超时)为止。如果超时仍然没有找到符合条件的元素,则会抛出一个TimeoutException异常
常用等待条件:
presenceOfElementLocated(By locator)
: 等待元素出现,但不一定可见。visibilityOfElementLocated(By locator)
: 等待元素可见。elementToBeClickable(By locator)
: 等待元素可点击。
选择使用哪种等待
强制等待:
- 适用于调试阶段或极少数情况下,生产环境中不推荐使用。
隐式等待:
- 适用于整个应用程序的加载时间相对一致,且不需要针对具体操作单独设置等待时间的情况。
- 一次设置,对整个WebDriver会话中的所有查找操作都生效。
显式等待:
- 适用于复杂场景,不同页面或操作需要不同的等待条件和时间。
- 针对每个操作单独设置等待条件,更加灵活和精确。
总结
等待机制在自动化测试中至关重要,它们可以帮助确保测试脚本在执行操作前,页面元素已经加载完成。选择合适的等待机制,可以提高测试的可靠性和效率。
- 强制等待:简单直接,但不推荐在生产环境中使用。
- 隐式等待:适用于简单的场景,例如整个应用程序的加载时间相对一致,且不需要针对具体操作单独设置等待时间。
- 显式等待:适用于复杂的场景,例如不同页面或操作需要不同的等待条件和时间。
通常,显式等待和隐式等待可以结合使用,但需要小心处理,因为它们会同时影响等待时间。例如,设置隐式等待10秒,再设置显式等待5秒,那么实际等待时间可能会超过预期。因此,在使用显式等待时,最好将隐式等待设置为较短时间或不设置隐式等待。
版权归原作者 如果Null没有null 所有, 如有侵权,请联系我们删除。