网站推广的具体方法,wordpress需要多少运存,品牌好的建筑企业查询,我国空间站建造更多关于Selenium的知识请访问CSND论坛“兰亭序咖啡”的专栏#xff1a;专栏《Selenium 从入门到精通》
目录
目录
需要等待的场景
自己实现等待逻辑
Selenium 提供的三种等待机制
隐式等待#xff08;Implicit Waits#xff09;
隐式等待的优点
隐式等待的缺点 … 更多关于Selenium的知识请访问CSND论坛“兰亭序咖啡”的专栏专栏《Selenium 从入门到精通》
目录
目录
需要等待的场景
自己实现等待逻辑
Selenium 提供的三种等待机制
隐式等待Implicit Waits
隐式等待的优点
隐式等待的缺点
显式等待Explicit Waits
显式等待的优点
显式等待的缺点
自定义等待Custom Waits
自定义等待的优点
自定义等待的缺点
总结 需要等待的场景
在 UI 自动化时我们通常需要等待比如以下场景 登录后页面会跳转我们需要等待页面完全加载否则没ready访问元素会找不到点击搜索按钮后页面异步刷新我们需要等待加载框消失否则结果还没有update拿到错误的数据页面满足部分条件后预定按钮才会可以点击我们需要等待它变成激活状态否则按钮还是disabled的状态出现点击报错……
总之这些等待对于我们测试的稳定性和正确性非常重要。 自己实现等待逻辑
最简单的方法是我们自己写一个While循环不断地检查条件是否满足。
while(true){if(checkCondition()){doSomeThing();}else{Thread.sleep(n秒);}
}
不过这么做不但麻烦自己实现也容易出错。值得庆幸的是Selenium 就提供了内置的机制帮助我们实现等待的功能。 学习中可以造轮子帮助我们理解原理但是生产项目中尽量用成熟的轮子。 Selenium 提供的三种等待机制
Selenium 查找元素默认是没有等待的也就是说找到了就返回WebElement否则就抛出异常。
我们测试一下没有配置任何等待
Test
public void testDefault(){WebDriver driver null;long begin 0;try{driver new ChromeDriver();driver.get(https://mail.163.com);begin System.currentTimeMillis();WebElement element driver.findElement(By.id(inexistence));}finally {long end System.currentTimeMillis();log.info(花费时间{}毫秒, end-begin);driver.close();}
}
日志打印-- 花费时间100毫秒这个很短的时间是findElement本身执行遍历dom需要的一些时间
抛出异常 org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {method:css selector,selector:#inexistence} Selenium 提供了等待机制我们可以通过配置或者调用很方便的实现我们等待的需求。
Selenium 主要分为
显式等待Explicit Waits隐式等待Implicit Waits自定义等待Custom Waits 下面我们分别介绍它们。 隐式等待Implicit Waits
隐式等待是全局设置设置一次后对整个WebDriver实例生命周期内的所有查找元素操作生效。
它会让Webdriver在寻找元素时如果元素没有立即找到就等待一段时间再查找直到超过设定的最大时间或者找到元素为止。
下面是我们显式等待的测试代码
Test
public void testImplicit (){WebDriver driver null;long begin 0;try{driver new ChromeDriver();// 设置隐式等待时间为10秒driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));driver.get(https://mail.163.com);WebElement element driver.findElement(By.id(inexistence));}finally {long end System.currentTimeMillis();log.info(花费时间{}毫秒, end-begin);driver.close();}
}
其实相对于默认的机制我们只是加了一行配置的代码
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
但是效果却非常大
日志打印-- 花费时间10129毫秒去除方法本身的执行时间等待时间大于就是10秒
抛出的异常还是找不到元素 org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {method:css selector,selector:#inexistence} 当然不是说一定要等待这么久如果找到了元素会立刻返回
等待时间只是超时时间。 隐式等待的优点
简单一条配置全局都有效。
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); 隐式等待的缺点
等待的时间是全局的但是不同元素、不同页面、甚至不同网络的加载情况不一样不能对每种元素设置不同的等待时间。 使用不当的话会对整个测试的效率造成非常大的影响。
比如我们很多地方会用检查一个元素存不存在来判断不同的情况。
Element ele findElement(XXX);
if(ele null){ // 当然默认找不到元素会抛异常而不是为null不过我们可以使用findElementsdoSometing();
}else{doOtherthing();
}
如果很多地方都这样检查那么花费的时间会很长很长 显式等待Explicit Waits
上面说过隐式等待是全局一致的如果我们想更灵活的等待对一些元素希望等待时间可以短一些对另一些希望能够多等一些时间这时显式等待就派上用场了。
Test
public void testExplicitWait(){WebDriver driver null;long begin 0;try{driver new ChromeDriver();driver.get(https://mail.163.com);begin System.currentTimeMillis();// 等待id为someId的元素出现WebElement element new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.presenceOfElementLocated(By.id(someId)));// 等待加载图标class为loading-spinner消失new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.invisibilityOfElementLocated(By.className(loading-spinner)));}finally {long end System.currentTimeMillis();log.info(花费时间{}毫秒, end-begin);driver.close();}
}
可以看到我们可以对不同的元素设置不同的等待时间
new WebDriverWait(driver, java.time.Duration.ofSeconds(10))
这些wait其实也是可以复用的比如10s的等待的Wait可以被用来检查各种元素。 还能对它们设置不同的条件比如等待元素的出现、消失
wait.until(ExpectedConditions.presenceOfElementLocated(By.id(someId)));
wait..until(ExpectedConditions.invisibilityOfElementLocated(By.className(loading-spinner)));
ExpectedConditions 类内置了常用的各种等待条件满足我们大部分的场景 更完整的列表请查看这个类的方法列表 显式等待的优点
更精细更灵活的控制
1. 对不同的元素设置不同的等待时间
2. 对不同的元素设置不同的等待条件 显式等待的缺点
更复杂维护起来也麻烦。
如果不是很熟悉乱使用容易适得其反。 自定义等待Custom Waits
显式等待看上去很强大了是不是就很完美了呢
特殊场景下如果你又更苛刻的要求你也可以定制化自己的等待进一步的更精细的控制等待比如 自定义重试检查的周期找不到抛异常时想根据Exception做一些处理因为隐式、显式等待超时后都是直接抛出Timeout异常的默认不做处理往外抛定制超时后的异常消息文本 Testpublic void test() {WebDriver driver null;long begin 0;try {driver new ChromeDriver();driver.get(https://mail.163.com);begin System.currentTimeMillis();WaitWebDriver wait new FluentWait(driver).withTimeout(Duration.ofSeconds(2)).pollingEvery(Duration.ofMillis(300)).ignoring(ElementNotInteractableException.class);wait.until(ExpectedConditions.visibilityOfElementLocated(By.className(no-no)));} finally {long end System.currentTimeMillis();log.info(花费时间{}毫秒, end - begin);driver.close();}} 自定义等待的优点
更灵活、更精细的控制 自定义等待的缺点
太复杂使用前请认真思考我们真的需要这么细致的控制吗 总结
本文介绍了4种等待机制包括默认的有了这些等待可以大大的提高我们测试的准确性和稳定性。这几种机制没有哪个最好我们需要根据实际的情况选择最合适的等待。