Selenium是ThoughtWorks公司研发的一个强大的基于浏览器的开源自动化测试工具,它通常用来编写web应用的自动化测试。早期也即Selenium1.x时期主要使用Selenium RC(Selenium Remote Control)进来自动化测试。Selenium2.x集成了Selenium和WebDriver的功能。
下图所示为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来编写相关的代码。
工作流程如下图所示:
具体过程为:
(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页面返回给浏览器
(1)Selenium RC不能处理本机键盘和鼠标事件
(2)Selenium RC不能处理弹出框、对话框(基本身份认证、文件上传/下载)事件
(3)Selenium RC使用Javascript注入技术,速度不够理想,稳定性大大依赖于Selenium内核对API翻译成的Javascript质量高低。
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/wd/hub/session/sessionId/url
,请求json内容:{"url":"http://www.qq.com"}
。比如查找一个classname为test的元素,请求地址后缀为/session/sessionId/element
,json内容{"using":"class_name","value":"test"}
。
(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"}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。