关闭

Selenium打开浏览器加载慢的原因

时间: 2018-11-08阅读: 2069标签: 测试

在自动化元素定位操作中经常使用智能等待来加强定位的强壮性,主要就是因为WebDriver没有提供页面加载场景的方法;在使用JavaScript知识的突然心生灵感,可以使用JavaScript来配合验证页面加载,结果发现我真是井底之蛙。


一、domcument.readyState

首先定位从Document对象出发,而Document对象是在html文档加载完成便可操作使用,所以判断文件装载完成即可;Document对象的readyState属性返回当前文档装载状态:

uninitialized 表示未开始载入
loading 载入中,下载了html并且开始加载
interactive 已加载完html内容
complete 已加载完html内容和下载解析了子资源(jscss、image),不包含ajax异步。
public static void pageDOMLoadComplete(){
       JavascriptExecutor js=(JavascriptExecutor) SeleniumMethod.ThreadDriver.get();
       try {
              while(!"complete".equals(JS.executeScript("return document.readyState"))){
                     Thread.sleep(2000);
       }
         logger.info("页面元素加载完成");
       } catch (Exception e) {
              // TODO: handle exception
              e.printStackTrace();
              logger.info("判断页面元素加载异常");
       }     
}

如上代码,如果结果返回的complete表示加载完成,这时候就可以开始元素定位操作。返回不是complete则使用线程循环等待,直到加载完成才跳出循环。

详细了解的建议去脑补一下浏览器对页面加载的过程。通过浏览器发送请求到服务器响应先得到html形成Document对象,浏览器解析html形成dom树开始加载,当加载dom树遇到外部资源时去请求外部资源,但加载dom树并不会等待会继续加载,当资源如JavaScript、css、图片等等加载完成这时候document.readyState的值变成complete。


二、Selenium加载策略

因为Selenium从头到位都没有任何判断页面加载完成的关键字;而结合document.readyState的返回来确定页面加载成功,然后再去执行定位操作,这样来说是个合理的思想。根据想法编写下面的代码:

WebDriver driver = new ChromeDriver();
driver.get("https://www.sina.com.cn/");
try {
	while(!"complete".equals(((JavascriptExecutor) driver).executeScript("return document.readyState"))) {
		Thread.sleep(1000);
	}
} catch(Exception e) {
	// TODO: handle exception
	e.printStackTrace();

}
driver.findElement(By.name("SerchKey")).sendKeys("软件测试");
driver.findElement(By.name("SearchSubButton")).click();
driver.quit();


上面代码利用JavaScript执行一段脚本document.readyState的值返回不是complete则一直循环并线程等待1S,直到返回的值是complete退出循环。

但是在代码运行后发现,从来都没有进入过循环。于是猜测,是get()方法在打开浏览器并访问URL时,是不是就已经判断过页面加载完成了?验证方法很简单,把循环去掉,代码直接打印document.readyState返回的值

System.out.print(((JavascriptExecutor)driver).executeScript("return document.readyState"));

得到的结果每次都是complete,验证确实get()方法后就已经页面加载成功了。在使用WebDriver时,每次打开浏览器都知道它并不会带有任何缓存数据,而是一个全新初始化的浏览器,这点只要用过Selenium的同学,并做过登录功能都应该知道,每次使用都需要重新登录,浏览器并不会保存任何cookie、缓存信息。就是因为这个原因,WebDriver每次调起浏览器并访问URL的时候因为没有缓存所以页面加载会非常慢(当然不仅仅是缓存,WebDriver还会去遍历一些其他东西,如虚拟网卡、代理配置等);这个慢的现象大多数是页面已经展示内容了,然后浏览器还在转圈加载,然而使用document.readyState来判断好像不现实了,因为WebDriver的get()方法默认就会等待页面加载完。所以思路就转化为,get()方法的探究。

通过官方资料查询,发现WebDriver有pageLoadStrategy加载策略这一说,地址如下:https://www.w3.org/TR/webdriver/#dfn-table-of-page-load-strategies,大家可以自己去瞧瞧。加载策略有如下三种:

none:没有说明对应关系
eager:对应ducument readiness state为”interactive”
normal:对应ducument readiness state为”complete”

从上面三种加载策略可以看到,官方除了none这种没有具体说明外,另外两种对应的正式document.readyState返回的状态。而默认的加载策略是normal,所以再次验证为什么使用document.readyState得到的值是complete。验证代码如下:

DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability("pageLoadStrategy", "none");
WebDriver driver = new ChromeDriver(capabilities);
driver.get("https://www.sina.com.cn/");
System.out.println(((JavascriptExecutor) driver).executeScript("return document.readyState"));
driver.findElement(By.name("SerchKey")).sendKeys("软件测试");
driver.findElement(By.name("SearchSubButton")).click();
System.out.println(((JavascriptExecutor) driver).executeScript("return document.readyState"));
driver.quit();


 执行代码,打印document.readyState返回的结果是loading;在使用findElement查找元素时报错“Unable to locate element”。当加载策略为none时,对应document.readyState结果是loading的时候,页面还在加载中,进行元素查找会报错,这很好理解,Dom树还在加载过程中,是无法解析任何元素的查找的,所以报错。

接下来分别尝试了eager加载策略,需要注意一点的是Chrome浏览器并不支持这种加载策略,所以改为了Firefox验证。

DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability("pageLoadStrategy", "eager");
WebDriver driver = new FirefoxDriver(capabilities);


其他代码不变,执行代码打印document.readyState返回的结果是interactive,但是不同的是使用findElement查找元素没有报错,并且全部执行成功。当加载策略为eager,页面加载结果interactive时,整个DOM树加载完成,这时候就已经可以定位元素并执行操作了;根据document.readyState与WebDriver的加载策略得出以下结论:


(1)loading与none

 DOM树 载入中,也就是说已经下载了html并且开始加载;这时候是无法查找元素的,get()方法的执行时间非常短,可以马上执行get()方法后面的代码。所以这时候就可以使用下面代码再次进行判断后再执行。

while(!"complete".equals(((JavascriptExecutor)driver).executeScript("return document.readyState"))){}

 这样的作法好像与加载策略的默认方法没什么不同,但是WebDriver的get()方法可不仅仅是等待页面为complete而已,它还会去判断一些浏览器其他的配置。

这种情况还有一种不建议使用的方式,就是使用隐式等待,每次查找元素找不到时,等待一定时间。隐式等待在当前driver的整个生命周期中都生效,是非常适合配合none这种加载策略的。

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


(2)interactive与eager

已加载完html内容,但是没有解析子资源;这时候DOM树加载完成,并且去请求子资源了,是可以查找元素并正确返回了。有个弊端就是如果一些数据是通过JavaScript去赋值的,这时候查找元素某些属性数据可能得到空。


(3)complete与normal

 已加载完html内容和下载解析了子资源(JavaScript、css、image),不包含ajax异步。前面应该都没疑问,重要的是ajax异步请求的加载。如果页面上一些数据是通过ajax异步去请求并加载的,同样在ajax请求中数据响应没有及时回来的情况下,拿到的也是空。当然这并不需要担心,只要不是太大数据请求响应还是非常快速的。


原文来源:https://blog.csdn.net/ouyanggengcheng/article/details/83036680


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/1294

Jest单元测试框架

在命令行工具中输入以下命令,初始化前端项目并生成package.json:babel-jest、 babel-core、 regenerator-runtime、babel-preset-env这几个依赖是为了让我们可以使用ES6的语法特性进行单元测试

vue-cli3 配置开发-测试环境

首先介绍一下本项目的背景,是基于 vue-cli3.1.1 的单页应用,目前测试环境和生产环境都在线上,并且都在同一个域名下,其中生产环境部署在根目录下,测试环境部署在名为 test 的子目录下,根据生产环境和测试环境的不同

项目经理基本技能之测试篇

近年来,各种软件发开技术大行其道,让IT从业人员应接不暇,忙的一塌糊涂。可是,从项目管理角度来说,光有一批技术达人是不够的,测试的质量,文档的完毕也是必不可少,同时也是为节省项目成本,提高产品质量。

使用 React Testing Library 和 Jest 完成单元测试

构建一个 web 应用对于我们来说,并非什么难事。因为有很多足够多优秀的的前端框架(比如 React,Vue 和 Angular);以及一些易用且强大的UI库(比如 Ant Design)为我们保驾护航,极大地缩短了应用构建的周期。

你需要了解的前端测试“金字塔”

如果您正在测试前端应用程序,则应该了解前端测试金字塔。在本文中,我们将看到前端测试金字塔是什么,以及如何使用它来创建全面的测试套件。

使用 QUnit 进行JavaScript单元测试

QUnit是一个强大的JavaScript单元测试框架。他可用于jQuery,jQuery UI和jQuery Mobile项目,以及任何使用JavaScript代码编写的项目的测试。

性能测试vs压力测试vs负载测试

软件测试包括不同的测试实践,比如单元测试、集成测试、UAT测试和可访问性测试等。每种测试实践在软件开发生命周期(SDLC)中都有重要的地位和作用。

Jest 初学者教程:JavaScript 测试入门

在编程术语中,测试意味着检查我们的代码是否符合某些期望。例如:一个名为 “ transformer” 的函数应在给定某些输入的情况下返回期望的输出。测试类型很多,但简单来说测试分为三大类:

测试工具比较:选Jest,不选Mocha

Jest的未来看起来非常令人激动!看到Jest推陈出新如此快速,我感觉它将很快成为整个React生态系统中大部分项目的首选工具。我建议,应该把测试迁移到Jest上去。

React 现代化测试

测试用例的书写是一个风险驱动的行为, 每当收到 Bug 报告时, 先写一个单元测试来暴露这个 Bug, 在日后的代码提交中, 若该测试用例是通过的, 开发者就能更为自信地确保程序不会再次出现此 bug。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!