selenium原理

Selenium是ThoughtWorks公司研发的一个强大的基于浏览器的开源自动化测试工具,它通常用来编写web应用的自动化测试。早期也即Selenium1.x时期主要使用Selenium RC(Selenium Remote Control)进来自动化测试。Selenium2.x集成了Selenium和WebDriver的功能。

一、Selenium RC

1. Selenium RC的组成

下图所示为Selenium RC的工作原理:


(1)Selenium Server

        Selenium Server负责控制浏览器行为,总的来说,Selenium Server主要包括3个部分:Launcher、Http Proxy、Selenium Core。其中Selenium Core是被Selenium Server注入到浏览器页面中的,它其实就是一堆Javascript函数的集合。自动化测试的过程是:Selenium RC启动一个Selenium Server,将操作web元素的API调用转化为一段段Javascript,在Selenium内核启动浏览器之后注入这段Javascript函数即Selenium Core,通过这些Javascript函数,我们才可以实现用程序对浏览器进行操作。(Javascript可以获取并调用页面的任何元素,自如的进行操作)

(2)Client Libraries

写测试用例时用来控制Selenium Server的库。测试用例通过调用Client Libraries来编写相关的代码。

2. Selenium RC与Testcase的关系

工作流程如下图所示:


具体过程为:

(1)测试用例通过Client Libraries的接口向Selenium Server发送Http请求,要求和Selenium Server建立连接

(2)Selenium Server的Launch启动浏览器,把Selenium Core加载入浏览器页面中,并发浏览器的代理设置为Selenium Server的Http Proxy。

(3)测试用例通过Client Libraries的接口向Selenium Server发送Http请求,Selenium Server对请求进行解析,然后通过Http Proxy发送JS命令通知Selenium Core执行操作浏览器的动作。

(4)Selenium Core接收到指令后,执行操作

(5)浏览器收到新的页面请求信息,于是发送Http请求,请求新的web页面。Selenium Server会接收到所有由它启动的浏览器发动的请求。

(6)Selenium Server接收到浏览器发送的Http请求后,自己重组Http请求,获取对应的web页面

(7)Selenium Server的Http Proxy把接收的Web页面返回给浏览器

3. Selenium RC的缺点

(1)Selenium RC不能处理本机键盘和鼠标事件

(2)Selenium RC不能处理弹出框、对话框(基本身份认证、文件上传/下载)事件

(3)Selenium RC使用Javascript注入技术,速度不够理想,稳定性大大依赖于Selenium内核对API翻译成的Javascript质量高低。

二、WebDriver

      WebDriver提供了另外一种方式与浏览器进行交互。那就是利用浏览器原生的API,封装成一套更加面向对象的Selenium WebDriver API,直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的)。由于使用的是浏览器的原生API,速度大大提高,而且调用的稳定性交给了浏览器厂商本身,显然是更加科学。然而带来的一些副作用就是,不同的浏览器厂商,对Web元素的操作和呈现存在不同程度的差异,这就要求Selenium WebDriver要分浏览器厂商的不同,提供不同的实现,例如Chrome有专门的ChromeDriver,Firefox有FirefoxDriver等等。

        WebDriver Wire协议是通用的,也就是说不管是FirefoxDriver还是ChromeDriver,启动之后都会在某一个端口启动基于这套协议的Web Service。例如ChromeDriver初始化成功之后,默认会从http://localhost:46350开始,而FirefoxDriver从http://localhost:7055开始。后续我们调用WebDriver的任何API,都需要借助一个ComandExecutor发送一个命令,实际上是一个HTTP request给监听端口上的Web Service。在我们的HTTP request的body中,会以WebDriver Wire协议规定的JSON格式的字符串来告诉Selenium我们希望浏览器接下来做什么事情。

工作流程如下图所示:

具体过程如下:

(1)实例化WebDriver,Selenium首先会确认浏览器的native component是否存在可用而且版本匹配。若匹配则在目标浏览器里启动一整套Web Service。这套Web Service使用了Selenium自己设计定义的协议,名字叫做The WebDriver Wire Protocol。这套协议非常之强大,几乎可以操作浏览器做任何事情,包括打开、关闭、最大化、最小化、元素定位、元素点击、文件上传等等

(2)发送请求时,用WebDriver的HttpCommandExecutor类将命令转换为URL作为value,命令作为key一起存入map作为request,同时会在request的body中存放相应的By Xpath、id、name。实际发送的URL都是相对路径,后缀多以/session/:sessionId开头,这也意味着WebDriver每次启动浏览器都会分配一个独立的sessionId,多线程并行的时候彼此之间不会有冲突和干扰。比如我们常用到的find_element_by_class_name这个接口,会转化为/session/:sessionId/element这个url,然后在发出Http Request Body内再附上具体的参数,比如class name的值。比如我们要访问某一个网站,请求地址为:http://localhost:46350/session/e9c37ea97fe23d3026d06e4a5d109707/url,请求json内容:{"url":"http://www.qq.com","sessionId": "e9c37ea97fe23d3026d06e4a5d109707"}。比如查找一个xpath为//input[@type='text']的元素,请求地址后缀为/session/e9c37ea97fe23d3026d06e4a5d109707/element,json内容{"using": "xpath", "value": "//input[@type='text']", "sessionId": "e9c37ea97fe23d3026d06e4a5d109707"}。

(3)收到并执行了这个操作之后,也会回复一个Http Response。内容也是Json,会返回找到的element的各种细节,比如text、CSS selector、tag name、class name等等。比如:

{"sessionId":"XXXXX","status":0,"state":"success","value":{"ELEMENT":"2"},"class":"XXX","hCode":"XXX"}


我们可以把WebDriver驱动浏览器类比成出租车司机开出租车。

在开出租车时有三个角色:

乘客:他/她告诉出租车司机去哪里,大概怎么走

出租车司机:他按照乘客的要求来操控出租车

出租车:出租车按照司机的操控完成真正的行驶,把乘客送到目的地


在WebDriver中也有类似的三个角色:

工程师写的自动化测试代码:自动化测试代码发送请求给浏览器的驱动(比如火狐驱动、谷歌驱动)

浏览器的驱动:它来解析这些自动化测试的代码,解析后把它们发送给浏览器

浏览器:执行浏览器驱动发来的指令,并最终完成工程师想要的操作。

所以在这个类比中:

1. 工程师写的自动化测试代码就相当于是乘客

2. 浏览器的驱动就相当于是出租车司机

3. 浏览器就相当于是出租车


下面再从技术上解释下WebDriver的工作原理:

从技术上讲,也同样是上面的三个角色:

1. WebDriver API(基于Java、Python、C#等语言)

对于java语言来说,就是下载下来的selenium的Jar包,比如selenium-java-3.8.1.zip包,代表Selenium3.8.1的版本

2. 浏览器的驱动(browser driver)

每个浏览器都有自己的驱动,均以exe文件形式存在

比如谷歌的chromedriver.exe、火狐的geckodriver.exe、IE的IEDriverServer.exe

3. 浏览器

浏览器当然就是我们很熟悉的常用的各种浏览器。

那在WebDriver脚本运行的时候,它们之间是如何通信的呢?为什么同一个browser driver即可以处理java语言的脚本,也可以处理python语言的脚本呢?让我们来看一下,一条Selenium脚本执行时后端都发生了哪些事情:

对于每一条Selenium脚本,一个http请求会被创建并且发送给浏览器的驱动

浏览器驱动中包含了一个HTTP Server,用来接收这些http请求

HTTP Server接收到请求后根据请求来具体操控对应的浏览器

浏览器执行具体的测试步骤

浏览器将步骤执行结果返回给HTTP Server

HTTP Server又将结果返回给Selenium的脚本,如果是错误的http代码我们就会在控制台看到对应的报错信息。

为什么使用HTTP协议呢?

因为HTTP协议是一个浏览器和Web服务器之间通信的标准协议,而几乎每一种编程语言都提供了丰富的http libraries,这样就可以方便的处理客户端Client和服务器Server之间的请求request及响应response,WebDriver的结构中就是典型的C/S结构,WebDriver API相当于是客户端,而小小的浏览器驱动才是服务器端。

那为什么同一个浏览器驱动即可以处理Java语言的脚本,也可以处理Python语言的脚本呢?

这就要提到WebDriver基于的协议:JSON Wire protocol。

JSON Wire protocol是在http协议基础上,对http请求及响应的body部分的数据的进一步规范。

我们知道在HTTP请求及响应中常常包括以下几个部分:http请求方法、http请求及响应内容body、http响应状态码等。

常见的http请求方法:

GET:用来从服务器获取信息。比如获取网页的标题信息

POST:向服务器发送操作请求。比如findElement,Click等

http响应状态码:

在WebDriver中为了给用户以更明确的反馈信息,提供了更细化的http响应状态码,比如:

7: NoSuchElement

11:ElementNotVisible

200:Everything OK

现在到了最关键的http请求及响应的body部分了:

body部分主要传送具体的数据,在WebDriver中这些数据都是以JSON的形式存在并进行传送的,这就是JSON Wire protocol。

JSON是一种数据交换的格式,是对XML的升级与替代,下面是一个JSON文件的例子:

  {

    "firstname": "Alex",

    "lastname": "Smith",

    "moble": "13300000000"

  }


下面的例子是WebDriver中在成功找到一个元素后JSON Wire Protocol的返回:

{"status" : 0, "value" : {"element" : "123422"}}

所以在Client和Server之间,只要是基于JSON Wire Protocol来传递数据,就与具体的脚本语言无关了,这样同一个浏览器的驱动就即可以处理Java语言的脚本,也可以处理Python语言的脚本了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • Selenium 官网Selenium WebDriver官网webdriver实用指南python版本 WebD...
    顾顾314阅读 46,954评论 0 34
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • Selenium是一款强大的基于浏览器的开源自动化测试工具,最初由 Jason Huggins 于 2004 年在...
    FifiZhuang阅读 7,575评论 5 71
  • 转自Selenium WebDriver注意:本章内容官方团队正在完善中。 介绍 WebDriver### Sel...
    抓兔子的猫阅读 7,701评论 2 22
  • 这篇文章在介绍官网的同时使用了比较多的脚本示例,示例里遇到的问题有部分在本篇文章进行了解释,还有一篇文章专门记录了...
    顾顾314阅读 12,898评论 3 32