摘要
Selenium是一系列基于web的界面自动化测试工具集合,提供了全面的测试函数,用于支持B/S类应用的界面自动化测试。 Selenium可以直接控制浏览器完成各种操作,支持多个平台、多种浏览器、多种编程语言的测试脚本。
本文主要阐述了selenium 1和Webdriver执行自动化测试脚本的原理,并通过一个简单的自动化测试脚本实例进行原理剖析。
关键字:自动化测试、selenium 1、webdriver
一、selenium整体框架
Selenium的核心selenium core基于JsUnit,完全由JavaScript编写,因此可运行于任何支持JavaScript的浏览器上,支持的浏览器包括IE、Firefox、chrome等。
Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。这个工具的主要功能包括:测试与浏览器的兼容性(测试应用程序是否能够在不同浏览器和操作系统上运行)、测试系统功能(测试功能和用户需求)。
selenium支持自动录制和生成测试脚本,可生成JAVA、python、C#等不同语言的测试脚本。selenium包含selenium IDE、selenium webdriver、selenium remote control(RC)和selenium Grid等组件,如图1所示。
图1 selenium框架
Selenium IDE是一个集成测试工具,被嵌套在firefox浏览器中,作为firefox浏览器的一个插件来使用。测试人员可以通过selenium IDE来录制网页界面上的操作,可以对录制的动作进行编辑、调试以及快速回放。将用户在浏览器中执行的操作记录下来,生成各种形式的脚本,并可将这些脚本保存供以后使用和维护。
Selenium 1 (selenium-RC)是selenium最主要的测试工具之一,它所具有的某些功能即使是新版的selenium 2也无法支持。它能够通过多种语言(JAVA、JavaScript、Ruby、PHP、Python、Perl和C#)编写测试代码,同时能够支持几乎所有浏览器的测试。
Selenium 2,通常称为webdriver,主要功能集成了selenium 1以及webdriver(webdriver曾经是selenium的竞争对手)。也就是说,Selenium 2是selenium和webdriver两个项目的合并,即Selenium 2兼容Selenium,它既支持selenium API(应用程序编程接口)也支持Webdriver API。对比selenium 1时代的selenium RC,webdriver优势明显。
Selenium RC通过selenium server把javascript脚本注射到浏览器中,然后通过特定的测试脚本调用javascript命令,实现与浏览器的交互操作。webdriver通过原生浏览器支持或者浏览器扩展直接控制浏览器,比Selenium 1更简单易学,并且速度大幅提高,调用的稳定性取决于浏览器本身,更加科学。相应产生的问题就是,不同的浏览器厂商,对web元素的操作和呈现多少会有一些差异,这就直接导致了selenium webdriver要区分浏览器厂商,提供不同的实现。
Selenium Grid使得selenium 能同时并行地、在不同的环境上运行多个测试任务,极大地加快了web应用的功能测试。
二、Selenium 1工作原理
Selenium 1是selenium中最主要的第一代测试工具,相比于selenium 2,它更加成熟、稳定,能支持几乎所有浏览器的测试。
Selenium 1的缺点是:
- 编码方式是面向过程而非面向对象,易用性较差;
- 通过Selenium Core间接驱动浏览器,运行速度不如webdriver。下面简单介绍一下selenium 1的工作原理。
Selenium 1包含的主要组件有:
- Selenium服务器:负责启动或关闭浏览器;解释和运行从测试程序中传来的selenese命令(selenese是seleniumIDE中使用的命令集),并可以扮演HTTP代理的角色;捕获和验证在浏览器和被测试的应用程序之间传递的HTTP消息。
- 客户端库文件提供了各种编程语言和selenium RC服务器之间的接口。
图2 selenium1架构
2.1 Selenium服务器
Selenium服务器用于接收测试程序传来的selenium命令,解释并执行他们,然后向测试程序反馈测试的结果。Selenium服务器捆绑了Selenium-core并自动将其注入浏览器,该步骤在测试程序打开浏览器(调用客户端文件的API函数)时执行。Selenium-core是JavaScript程序,也就是说,它是一系列JavaScript函数,用于调用浏览器内置的JavaScript解释器,以解释和执行selenese命令
该服务器同样可以接收来自测试程序的HTTP GET/POST请求的selenese命令,这意味着可以使用任何支持HTTP请求的编程语言来编写测试代码。
2.2 Selenium客户端库文件
客户端库文件提供了对编程的支持,这样就可以自己设计程序来运行selenium命令。对于每一种支持的编程语言,都有不同的客户端库文件。Selenium客户端库文件提供了编程接口,用于在程序中运行selenium命令。
客户端库文件可以生成selenese命令,然后将其传递到selenium服务器,对被测试的应用程序执行指定的动作或者测试。客户端文件也可以接收命令执行的结果,并将其传递给应用程序,应用程序可以根据返回结果判断当前测试是通过还是失败。
因此要创建测试程序,只需要通过客户端库文件API编写程序,用它来执行一系列Selenium命令。也可以在Selenium IDE中创建Selenese测试脚本,导出成客户端驱动的API函数调用,如图3所示。
图3 导出selenium1执行脚本
三、webdriver工作原理
这部分具体描述一下webdriver工作原理。引用一个形象的类比,可以把webdriver驱动浏览器类比成出租车司机开出租车,这个场景中有三个主要角色:
- 乘客:告诉出租车司机目的地,以及大概路线
- 出租车司机:按照乘客的要求操控出租车
- 出租车:按照司机的操控完成实际的行驶,把乘客送到目的地
在webdriver中也有三个类似的角色,自动化测试脚本代码相当于乘客,浏览器的驱动相当于出租车司机,浏览器相当于出租车:
- 自动化测试脚本代码:自动化测试代码发送请求给浏览器的驱动(例如火狐、chrome驱动)
- 浏览器的驱动:解析自动化测试代码,解析后把结果发送给浏览器
- 浏览器:执行浏览器驱动发出的指令,完成实际的操作
具体的脚本执行过程是:
- 对于每一条Selenium脚本,会创建一个http请求并发送给浏览器的驱动
- 浏览器驱动中包含了一个HTTP Server,用来接收http请求
- HTTP Server接收到请求后根据请求来具体操控对应的浏览器
- 浏览器执行具体的测试步骤
- 浏览器将步骤执行结果返回给HTTP Server
- HTTP Server又将结果返回给Selenium脚本,如果是错误的http代码,就可以在控制台看到对应的报错信息。
同一个浏览器驱动既可以处理C#语言的脚本,也可以处理Python语言的脚本,这是因为:HTTP协议是一个浏览器和Web服务器之间通信的标准协议,几乎每一种编程语言都提供了丰富的http库,可以方便的处理客户端和服务器端之间的请求与响应,http请求及响应包括:http请求方法、http请求及响应内容body、http响应状态码等。
常见的http请求方法有:
- GET:用来从服务器获取信息,比如获取网页的标题信息等。
- POST:向服务器发送操作请求,比如click,findElement等。
http响应状态码用来判断请求的结果。
Body部分主要传送具体的数据,在webdriver中以JSON报文的形式存在并传送,例如:
Webdriver使用的协议是JSON Wire protocol,该协议是在http协议基础上,对http请求及响应的body数据进行规范。当用户新建webdriver时,selenium首先确认浏览器的native component是否存在、可用而且版本匹配。若通过确认,则在浏览器启动web service服务。JSON Wire protocol协议功能强大,几乎可以操作浏览器做任何事情,包括打开、关闭、最大化、最小化、元素定位、元素点击、上传文件等。
JSON Wire protocol是通用的,不管firefoxDriver还是ChromeDriver,启动之后会在某一端口基于该协议启动web service。例如firefoxDriver初始化成功后,默认会从http://localhost:7055开始。在调用webdriver API时,需要借助CommandExecutor发送命令,实际是向web service发送一个http request,在该request的body中,以JSON格式调用selenium执行其余操作。
四、具体实例介绍(基于webdriver的测试脚本)
本部分介绍一个最简单的自动化测试脚本,该脚本实现科技管理工作台(ITA)的登录功能:输入账号和密码并点击登录。该脚本可以通过Selenium IDE录制,导出成JAVA语言脚本,也可以直接编写JAVA代码生成。主要脚本如下:
4.1 打开网页
下面的代码实现打开firefox浏览器并跳转到ITA登陆页面:
Webdriver driver = new FirefoxDriver();//实例化一个driver
driver.get(“http://ita.abc/ita/login.action”);
在执行driver.get(“http://ita.abc/ita/login.action”);代码时,测试代码向server发送了如下的请求:
POST
session/sessionId/url
post_data{“url”:”http://ita.abc/ita/login.action”}
通过post方式请求localhost:port/hub/session/session_id/url地址,并请求浏览器完成跳转url的操作。
如果上述请求是可接受的,server会跳转到该post data包含的url,并返回如下的response:
{“name”:”get”,”sessionId”:”******”,”status”:0,”value”:””}
该response中包含如下信息:
- Name:server端实现方法的名称,这里是get,表示跳转到指定url
- sessionId:当前session的id
- Status:请求执行的状态码,非0表示未正确执行,这里是0,表示执行成功
- Value:请求的返回值,这里返回值为空。如果请求的是页面的title,value将被赋值为title的值。
4.2 元素定位方式
对于大多数selenium命令,都需要一个目标位置,该位置在web应用程序的上下文中唯一地定义web元素。
在Selenium IDE中,可以在每条录制命令中的Target选择该元素的定位方式,如图4所示:
图4 seleniumIDE定位方式
在webdriver中一共有8种定位策略,具体列表如下:
图5 webdriver定位方式
以id为例说明:
图6 ITA登陆界面
要在用户名输入框输入内容,可以通过 id= “userNameInput”作为定位条件获取该对象。如图7页面源码中,可看出,id=“userNameInput”可唯一标示用户名输入框。
代码driver.findElement(By.id("userNameInput"))
表示寻找id
为“userNameInput”的元素,在获取页面元素后,就可以对该页面元素进行各种操作了。
图7 页面元素
4.3 元素操作
常用的元素操作方法有如下几种:
- sendKeys()方法用于为input元素输入文本
- Click()方法用于执行单击元素的操作
- Clear()方法用于清空input元素的值
- Submit()方法用于对指定元素所在的form进行提交操作
表示找到id为userNameInput输入框之后,填写用户名信息。
五、总结
Selenium包含selenium IDE、seleniumwebdriver、selenium remote control(RC)和selenium Grid等组件。
Selenium 1客户端库文件可以生成selenese命令,然后将其传递到selenium服务器,Selenium服务器接收测试程序传来的selenium命令,通过selenium core操控浏览器,并向测试程序反馈测试的结果;webdriver直接驱动浏览器进行各项操作,执行速度更优,易用性更强,但是webdriver对浏览器版本有一定的依赖性,在版本升级后,需要下载新的驱动程序。
来源:IDCF社区
作者:程伟静