Selenium常用的等待方式
为什么需要等待?
在做自动化测试时,设计一些测试用例时,一些步骤需要等到上一步骤完成才能执行,这时候就需要等待上一步的完成,用等待来判断,什么时候才可以进行下一步操作。
否则,如果上一步还没操作完,就执行下一步骤,那么可能会定位不到指定元素,元素状态不正确,验证不正确等异常。
例如,在登录时,输入地址,页面需要加载完成,才可以输入用户名密码。
例如,需要定位的元素在某个弹出框上,需要等待弹出框弹出后,才能定位到这个元素。
例如,需要验证查询结果的正确性,需要等到查询结果完成之后,再去定位需要查询的数据等等。
常用的三种等待方式
1. 强制等待
Thread.sleep(x) -- java; 等待x秒后,进行下一步操作。x是毫秒值。
强制等待x秒,强制让浏览器等待x秒,不管当前操作是否完成,是否可以进行下一步操作,都必须等待x秒时间。暂停当前进程,把cpu片段让给其他进程,减缓当前进程的执行。但是如果当前线程获取到的有锁,sleep不会让出锁。线程睡眠到期自动苏醒,并返回到可运行状态(就绪),不是运行状态。sleep()中指定的时间是线程不会运行的最短时间,sleep方法不能作为精确的时间控制。sleep()是静态方法,只能控制当前正在运行的线程。
使用时,java方法需要throws InterruptedException
缺点除了不能精确把握等待时间外,如果在用例中大量使用,会浪费不必要的等待时间,影响测试用例的执行效率。一般不建议使用,但是在弹窗处理,可以优先选择线程等待。
2. 隐式等待
使用方法:
页面加载超时: webdriver.manage().timeouts().pageLoadTimeout(x, TimeUnit.SECONDS); 设置等待时间,是对页面中的所有元素设置加载时间。
页面元素加载超时:webdriver.manage().timeouts().implicitlyWait(x, TimeUnit.SECONDS); --java 在x时间内,页面元素加载完成,便可进行下一步。在规定的时间范围内,浏览器在不停的刷新页面,直到找到相关元素或者时间结束。
异步脚本超时: webdriver.manage().timouts().setScriptTimeout(x, TimeUnit.SECONDS);
设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间结束,然后执行下一步操作。超出设定时间后则抛出找不到元素的异常。默认设置是0秒。一旦设置了隐式等待时间,它的作用范围就是webdriver对象实例的整个生命周期。
3.显示等待
WebDriverWait wait = new WebDriverWait(driver,10,1); //每隔1秒去调用一下until中的函数,默认是0.5秒,如果等待10秒还没有找到元素,则抛出TimeoutException/NoSuchElementException??异常。假设在第三秒就找到了这个元素,那么就不会多等待剩下的7秒,而是继续执行后续代码。
wait.unitl(new ExpectedCondition<WebElement>())
是针对某个特定的元素设置等待时间,如果在规定的时间范围内,没有找到元素,则会抛出异常,如果在规定的时间内找到了元素,则直接执行,即找到元素就执行相关操作。
配合使用的ExpectedCondition: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html, 继承自java.lang.Object
缺点使用相对比较复杂。优点是等待判断准确,不会浪费多余的等待时间,在用例中使用,可以提高执行效率。