0


UI自动化编写测试脚本的几种等待时间方法

背景:

为了提高脚本的稳定性,我们需要在脚本中增加等待时间,比如到某个指定页面,要等待页面完全加载出来后,才能找到页面上我们想要的元素,尽可能避免 元素找不到情况;

三种等待方式介绍

强制等待

Thread.sleep(3000);

// eg:publicstatic native voidsleep(long millis) throws InterruptedException;

最最最最容易 ,被大家常用的一种等待方法,但不推荐:

1.固定休眠时间设置,Java的Thread类里提供了休眠方法sleep,导入包后就能使用;

2.时间以毫秒 为单位;

3.以上执行到此时 不管什么线程就固定的等待三秒之后再接着执行后面的操作;

4.作用范围:仅作用于当前方法,当前操作之后休眠,一般在隐士等待和显示等待都不起作用时使用;

隐式等待(全局隐式等待)

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

// eg:
WebDriver driver =newFirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

AndroidDriver androidDriver=null;
androidDriver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);

在这里插入图片描述
//源码 selenium框架对外提供的接口,如下:

publicinterfaceTimeouts{
    WebDriver.Timeouts implicitlyWait(long var1, TimeUnit var3);

    WebDriver.Timeouts setScriptTimeout(long var1, TimeUnit var3);

    WebDriver.Timeouts pageLoadTimeout(long var1, TimeUnit var3);}

推荐使用的一种等待方法之一:

1.implicitlyWait()方法比sleep()方法智能,sleep()方法只能在一个固定的时间等待,而implicitlyWait()可以在一个时间范围内等待;

2.implicitlyWait()方法,两个参数:一个接受时间,第二个接受时间度量也就是时间单位,
可以设定查找页面元素的最大等待时间,调用findElement()时没有立刻定位到该元素,则程序会每间隔一段时间 轮询查找( 默认是 0.5s)尝试判断页面DOM中是否存在该元素,设定时间内找到则继续向下执行,若超过设定等待时长(eg:全局的等待10s)还没找到,抛出NoSuchElementException;

3.作用范围: 作用于全局 针对执行脚本的所有对象 driver对象整个生命周期内,即只要设置一次,后面不需要再设置 ,所有的findElement方法都会隐式等待指定时长(eg:以上设置的等待10s),如果再次设置,最后一次的这只就会覆盖前一次的效果;

显式等待

// eg:
#设置等待
WebDriverWait wait =newWebDriverWait(driver,10,0.5);
WebElement webElement = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
WebDriverWait类具体实现:
显式等待用到的两个类:
* WebDriverWait和ExpectedConditions两个类

public WebDriverWait(WebDriver driver, long timeOutInSeconds, long sleepInMillis) {
this(driver, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, sleepInMillis);
}
1.driver:浏览器驱动
2.timeOutInSeconds:最长超时时间,默认以秒为单位,timeOutInSeconds范围内,等待满足until()方法中的条件,即刻跳出等待
3.sleepInMillis:检测的间隔步长,默认为0.5s
//用于告诉WebDriver某些某些条件(ExpectedConditions预期条件)或者超过最长时间

// 源码umtil()方法,until是传入一个method作为参数public<V>Vuntil(Function<?superT,V> isTrue){
        long end =this.clock.laterBy(this.timeout.in(TimeUnit.MILLISECONDS));
        Throwable lastException =null;while(true){try{V value =isTrue.apply(this.input);if(value !=null&& Boolean.class.equals(value.getClass())){if(Boolean.TRUE.equals(value)){return value;}}elseif(value !=null){return value;}}catch(Throwable var9){
                lastException =this.propagateIfNotIgnored(var9);}if(!this.clock.isNowBefore(end)){
                String message =this.messageSupplier !=null?(String)this.messageSupplier.get():null;
                String toAppend = message ==null?" waiting for "+ isTrue.toString():": "+ message;
                String timeoutMessage = String.format("Timed out after %d seconds%s",this.timeout.in(TimeUnit.SECONDS), toAppend);throwthis.timeoutException(timeoutMessage, lastException);}try{this.sleeper.sleep(this.interval);}catch(InterruptedException var8){
                Thread.currentThread().interrupt();thrownewWebDriverException(var8);}}}
ExpectedCondition类具体实现:
// 源码elementToBeClickable()方法://底层也是调用WebDriver封装的 driver.findElement(by)publicstatic ExpectedCondition<WebElement>elementToBeClickable(final By locator){returnnewExpectedCondition<WebElement>(){public ExpectedCondition<WebElement> visibilityOfElementLocated = ExpectedConditions.visibilityOfElementLocated(locator);public WebElement apply(WebDriver driver){
                WebElement element =(WebElement)this.visibilityOfElementLocated.apply(driver);try{return element !=null&& element.isEnabled()? element :null;}catch(StaleElementReferenceException var4){returnnull;}}public String toString(){return"element to be clickable: "+ locator;}};}publicstatic ExpectedCondition<WebElement>visibilityOfElementLocated(final By locator){returnnewExpectedCondition<WebElement>(){public WebElement apply(WebDriver driver){try{return ExpectedConditions.elementIfVisible(ExpectedConditions.findElement(locator, driver));//关键查找元素的方法}catch(StaleElementReferenceException var3){returnnull;}}public String toString(){return"visibility of element located by "+ locator;}};}
整体关系图:在这里插入图片描述

推荐使用的一种等待方法之一:

1.显式等待与隐式等待相对,显式等待必须在每一个须要等待的元素前面进行声明,而隐式等待一般都是在要等待的对象之后声明,都属于智能等待方式;

2.设置一个超时时间和一个元素查找条件,在这个时间内不断寻找这个元素,超时找不到时就会报错;

3.作用范围:显式等待是针对单个某元素设置的等待时间,例如:每隔0.5秒检查一次是否出现,若是在5秒以前任什么时候出现,则继续向下,否则继续等待,超过5秒还没有出现则抛异常,默认抛出异常为:NoSuchElementException;

4.应用场景:
用来处理隐式等待无法解决的一些问题【等待指定的元素加载完成】,比如:文件上传(可以设置长一点),文件上传需要设置20s以上,但是如果设置隐式等待,它会在每个find方法都等这么长时间,一旦发现没有找到元素,就会等20s以后才抛出异常,影响case的执行效率,这时候就需要用显式等待,显式等待可以设置的长一点。

总结:

隐式等待和显式等待在本质上是一致的;
显式等待多了一个指定某元素设置超时时间;
在使用场景上,可使用隐式等待来作一个全局的控制;
若是某个控件比较特殊,须要更长的时间加载,好比十几秒或者更长,就可使用显式等待对其进行单独处理;
当然再程序中可以针对不同场景,两者结合使用;

标签: selenium 自动化

本文转载自: https://blog.csdn.net/qq_43787743/article/details/123780448
版权归原作者 々子非鱼 所有, 如有侵权,请联系我们删除。

“UI自动化编写测试脚本的几种等待时间方法”的评论:

还没有评论