selenium自动化测试原理和设计的分享
昨天参加了公司的一个自动化测试的分享,有一些收获,记录一下。
1.主流的web端的UI自动化测试工具
基于浏览器API: selenium2.0,Watir(IE Driver)
基于JS 进行驱动:selenium1.0,sahi(ruby)
基于Windows GUI :QTP,AutoIt
2.实现原理(这里只列举第一种,第二种我没有实践,暂不研究)
基于浏览器API:

这里我在网上看了一下selenium2的实现原理,跟这个差不多。
参考:https://blog.csdn.net/ant_ren/article/details/7970793
selenium的工作原理:
1.用CS设计方式,将浏览器看作是remote server,有它自己的端口,将selenium的脚本执行端看作client。
2.client发送http request(操作放在json里面)发送给web server端,转化为浏览器的API,再封装成执行命令CommandExecutor ,发给浏览器去用native的操作执行
3.浏览器执行后,再返回给client
简化为:webdriver把浏览器的原生API包装了一下,通过conmmandExecutor来给浏览器发送http request请求(操作写在json里面),通过设置的端口,去请求浏览器,将发送的请求转化成浏览器的原生的命令,再将浏览器的返回,装进httpResponse里面,发回给客户端。
画了一张图

其他博客里面,引用的开发者的图

3.UI自动化的原则
- 不依赖环境,不改变环境
- 隔离变量和不变量
- 代码尽可能复用
4.使用的设计模式
三层:
- 界面表示层:一个页面封装到一个类中,一个方法对应一个控件,主要是查找控件,复杂控件操作,比如表格,需要再界面表示层实现
- 业务逻辑层:调用界面表示层的控件操作,完成业务逻辑,一般一个函数封装一个简单的业务操作。
- 测试用例层:调用业务层的函数完成测试,并验证结果,尽量不依赖环境,不破坏环境,不要直接调用界面层函数
5.源码解读,我用的是appium,不过appium和selenium是同源的,可以用来参考。
findElements代码
Response response = execute(DriverCommand.FIND_ELEMENTS,
ImmutableMap.of("using", by, "value", using));
@SuppressWarnings("unchecked")
protected List<WebElement> findElements(String by, String using) {
if (using == null) {
throw new IllegalArgumentException("Cannot find elements when the selector is null.");
}
Response response = execute(DriverCommand.FIND_ELEMENTS,
ImmutableMap.of("using", by, "value", using));
Object value = response.getValue();
List<WebElement> allElements;
try {
allElements = (List<WebElement>) value;
} catch (ClassCastException ex) {
throw new WebDriverException("Returned value cannot be converted to List<WebElement>: " + value, ex);
}
for (WebElement element : allElements) {
setFoundBy(this, element, by, using);
}
return allElements;
}
findElement 返回的是执行语句的 response,执行语句如下,返回值是response
protected Response execute(String driverCommand, Map<String, ?> parameters) {
Command command = new Command(sessionId, driverCommand, parameters);
Response response;
long start = System.currentTimeMillis();
String currentName = Thread.currentThread().getName();
Thread.currentThread().setName(
String.format("Forwarding %s on session %s to remote", driverCommand, sessionId));
try {
log(sessionId, command.getName(), command, When.BEFORE);
response = executor.execute(command);
log(sessionId, command.getName(), command, When.AFTER);
if (response == null) {
return null;
}
// Unwrap the response value by converting any JSON objects of the form
// {"ELEMENT": id} to RemoteWebElements.
Object value = converter.apply(response.getValue());
response.setValue(value);
} catch (SessionNotFoundException e){
throw e;
} catch (Exception e) {
log(sessionId, command.getName(), command, When.EXCEPTION);
String errorMessage = "Error communicating with the remote browser. " +
"It may have died.";
if (driverCommand.equals(DriverCommand.NEW_SESSION)) {
errorMessage = "Could not start a new session. Possible causes are " +
"invalid address of the remote server or browser start-up failure.";
}
UnreachableBrowserException ube = new UnreachableBrowserException(errorMessage, e);
if (getSessionId() != null) {
ube.addInfo(WebDriverException.SESSION_ID, getSessionId().toString());
}
if (getCapabilities() != null) {
ube.addInfo("Capabilities", getCapabilities().toString());
}
throw ube;
} finally {
Thread.currentThread().setName(currentName);
}
try {
errorHandler.throwIfResponseFailed(response, System.currentTimeMillis() - start);
} catch (WebDriverException ex) {
if (parameters != null && parameters.containsKey("using") && parameters.containsKey("value")) {
ex.addInfo(
"*** Element info",
String.format(
"{Using=%s, value=%s}",
parameters.get("using"),
parameters.get("value")));
}
ex.addInfo(WebDriverException.DRIVER_INFO, this.getClass().getName());
if (getSessionId() != null) {
ex.addInfo(WebDriverException.SESSION_ID, getSessionId().toString());
}
if (getCapabilities() != null) {
ex.addInfo("Capabilities", getCapabilities().toString());
}
Throwables.propagate(ex);
}
return response;
}
response的核心代码如下:执行command,然后用转化器将response的value转化成语句使用的代码
response = executor.execute(command);
……
Object value = converter.apply(response.getValue());
response.setValue(value);
这里的converter.apply,是JsonToWebElementConverter的方法,就是用来把返回的json串转化为element的转化器
public Object apply(Object result) {
if (result instanceof Collection<?>) {
Collection<?> results = (Collection<?>) result;
return Lists.newArrayList(Iterables.transform(results, this));
}
if (result instanceof Map<?, ?>) {
Map<?, ?> resultAsMap = (Map<?, ?>) result;
if (resultAsMap.containsKey("ELEMENT")) {
RemoteWebElement element = newRemoteWebElement();
element.setId(String.valueOf(resultAsMap.get("ELEMENT")));
element.setFileDetector(driver.getFileDetector());
return element;
} else if (resultAsMap.containsKey("element-6066-11e4-a52e-4f735466cecf")) {
RemoteWebElement element = newRemoteWebElement();
element.setId(String.valueOf(resultAsMap.get("element-6066-11e4-a52e-4f735466cecf")));
element.setFileDetector(driver.getFileDetector());
return element;
} else {
return Maps.transformValues(resultAsMap, this);
}
}
if (result instanceof Number) {
if (result instanceof Float || result instanceof Double) {
return ((Number) result).doubleValue();
}
return ((Number) result).longValue();
}
return result;
}
appium原理参考https://www.cnblogs.com/csj2018/p/9937511.html
selenium自动化测试原理和设计的分享的更多相关文章
- 《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)
1.简介 从这一篇开始介绍和分享Java+Selenium+POM的简单自动化测试框架设计.第一个设计点,就是支持跨浏览器测试. 宏哥自己认为的支持跨浏览器测试就是:同一个测试用例,支持用不同浏览器去 ...
- 《手把手教你》系列基础篇(九十五)-java+ selenium自动化测试-框架之设计篇-java实现自定义日志输出(详解教程)
1.简介 前面宏哥一连几篇介绍如何通过开源jar包Log4j.jar.log4j2.jar和logback实现日志文件输出,Log4j和logback确实很强大,能生成三种日志文件,一种是保存到磁盘的 ...
- 《手把手教你》系列基础篇之(一)-java+ selenium自动化测试-环境搭建(上)(详细教程)
1.简介 jmeter系列的文章结束,本来想趁热打铁顺别将Jmeter和接口测试介绍一下,但是感觉Jmeter时间太长了怕大家吃腻了,还有一个原因就是许多小伙伴们或者童鞋们私信问宏哥什么时候可以有ja ...
- Eclipse+Selenium自动化测试脚本设计V1.0
Eclipse+Selenium自动化测试脚本设计V1.0 http://www.docin.com/p-803032251.html
- 《手把手教你》系列基础篇(九十七)-java+ selenium自动化测试-框架设计篇-Selenium方法的二次封装和页面基类(详解教程)
1.简介 上一篇宏哥介绍了如何设计支持不同浏览器测试,宏哥的方法就是通过来切换配置文件设置的浏览器名称的值,来确定启动什么浏览器进行脚本测试.宏哥将这个叫做浏览器引擎类.这个类负责获取浏览器类型和启动 ...
- 从UI Automation看Windows平台自动化测试原理
前言 楼主在2013年初研究Android自动化测试的时候,就分享了几篇文章 Android ViewTree and DecorView Android自动化追本溯源系列(1): 获取页面元素 An ...
- Selenium自动化测试,接口自动化测试开发,性能测试从入门到精通
Selenium自动化测试,接口自动化测试开发,性能测试从入门到精通Selenium接口性能自动化测试基础部分:分层自动化思想Slenium介绍Selenium1.0/2.0/3.0Slenium R ...
- Selenium自动化测试Python五:WebDriver设计模式
WebDriver 设计模式 欢迎阅读WebDriver进阶讲义.本篇讲义将会重点介绍Selenium WebDriver 自动化框架的设计,着重使用Page Object设计模式,以及使用HTML测 ...
- selenium自动化测试框架之PO设计模式
面向对象的特性:封装.继承.多态.在自动化中一样适用,Selenium自动化测试中有一个名字常常被提及PageObject(思想与面向对象的特性相同),通过PO模式可以大大提高测试用例的维护效率. 传 ...
随机推荐
- SELECT IDENT_CURRENT(tableName)和自增长列的纠结
项目中要用到一个功能:主表主键为自增长,要求在插入主表数据前先获得主表要插入数据的主键ID值,用在插入子表时获取主键ID.在网上搜了一下,发现SELECT IDENT_CURRENT(TableNam ...
- 利用H5 FormData 实现表单中多图上传(可带其他如String类型数据)
本篇的具体思路来源于右侧网址:http://blog.csdn.net/qq_19551571/article/details/49977983 本篇代码有所修改,请具体区分. 本篇使用的是 form ...
- 学习android开发之路(一)页面布局
Android页面布局 1.Android页面布局一共分为6种: LinearLayout(线性布局).RelativeLayout(相对布局).TableLayout(表格布局).FrameLayo ...
- Ontology
本体网络(Ontology) 新一代分布式信任链网 在开始了解项目之前,让我们先看一段“第一财经”频道关于“本体网络”的介绍: 项目介绍 1摘要 类型 提供不同分布式应用场景的开放基础模块,构建跨链 ...
- SpringMVC 复杂对象数据绑定
表单在 web 页面上无处不在,有些表单可能很复杂,大部分表单里的输入项都会对应后端对象属性.SpringMVC 可以自动将表单值绑定到对象上!而且能绑定很复杂的对象!!这里就不写那些基本的表单绑定了 ...
- python3.7之12306抢票脚本实现
悲催的12306,彻底沦为各路抢票软件的服务提供方.元旦伊始,纯粹12306官网及APP抢票,愈一周的时间,仅到手一张凌晨3:55回家的站票.为远离脑残,无奈选择抢票软件,预购年后返沪车票.BTW,研 ...
- $.ajax ,ajax请求添加请求头,添加Authorization字段
beforeSend : function(request) { request.setRequestHeader("Authorization", sessionStorage. ...
- Luogu4389 付公主的背包(生成函数+多项式exp)
显然构造出生成函数,对体积v的物品,生成函数为1+xv+x2v+……=1/(1-xv).将所有生成函数乘起来得到的多项式即为答案,设为F(x),即F(x)=1/∏(1-xvi).但这个多项式的项数是Σ ...
- MT【256】2016四川高考解答压轴题
(2016四川高考数学解答压轴题)设函数$f(x)=ax^2-a-\ln x,a\in R$. 1)讨论$f(x)$的单调性;2)确定$a$的所有可能值,使得$f(x)>\dfrac{1}{x} ...
- 【CodeForces 717C】Potions Homework
BUPT 2017 summer training (for 16) #1G 题意 每个人有一个懒惰值,每个任务有个难度,一开始每个人的任务和懒惰值都为\(a_i\),完成任务时间是懒惰值乘以难度,现 ...