昨天参加了公司的一个自动化测试的分享,有一些收获,记录一下。

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自动化测试原理和设计的分享的更多相关文章

  1. 《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)

    1.简介 从这一篇开始介绍和分享Java+Selenium+POM的简单自动化测试框架设计.第一个设计点,就是支持跨浏览器测试. 宏哥自己认为的支持跨浏览器测试就是:同一个测试用例,支持用不同浏览器去 ...

  2. 《手把手教你》系列基础篇(九十五)-java+ selenium自动化测试-框架之设计篇-java实现自定义日志输出(详解教程)

    1.简介 前面宏哥一连几篇介绍如何通过开源jar包Log4j.jar.log4j2.jar和logback实现日志文件输出,Log4j和logback确实很强大,能生成三种日志文件,一种是保存到磁盘的 ...

  3. 《手把手教你》系列基础篇之(一)-java+ selenium自动化测试-环境搭建(上)(详细教程)

    1.简介 jmeter系列的文章结束,本来想趁热打铁顺别将Jmeter和接口测试介绍一下,但是感觉Jmeter时间太长了怕大家吃腻了,还有一个原因就是许多小伙伴们或者童鞋们私信问宏哥什么时候可以有ja ...

  4. Eclipse+Selenium自动化测试脚本设计V1.0

    Eclipse+Selenium自动化测试脚本设计V1.0 http://www.docin.com/p-803032251.html

  5. 《手把手教你》系列基础篇(九十七)-java+ selenium自动化测试-框架设计篇-Selenium方法的二次封装和页面基类(详解教程)

    1.简介 上一篇宏哥介绍了如何设计支持不同浏览器测试,宏哥的方法就是通过来切换配置文件设置的浏览器名称的值,来确定启动什么浏览器进行脚本测试.宏哥将这个叫做浏览器引擎类.这个类负责获取浏览器类型和启动 ...

  6. 从UI Automation看Windows平台自动化测试原理

    前言 楼主在2013年初研究Android自动化测试的时候,就分享了几篇文章 Android ViewTree and DecorView Android自动化追本溯源系列(1): 获取页面元素 An ...

  7. Selenium自动化测试,接口自动化测试开发,性能测试从入门到精通

    Selenium自动化测试,接口自动化测试开发,性能测试从入门到精通Selenium接口性能自动化测试基础部分:分层自动化思想Slenium介绍Selenium1.0/2.0/3.0Slenium R ...

  8. Selenium自动化测试Python五:WebDriver设计模式

    WebDriver 设计模式 欢迎阅读WebDriver进阶讲义.本篇讲义将会重点介绍Selenium WebDriver 自动化框架的设计,着重使用Page Object设计模式,以及使用HTML测 ...

  9. selenium自动化测试框架之PO设计模式

    面向对象的特性:封装.继承.多态.在自动化中一样适用,Selenium自动化测试中有一个名字常常被提及PageObject(思想与面向对象的特性相同),通过PO模式可以大大提高测试用例的维护效率. 传 ...

随机推荐

  1. 在IWMS中的分页效果

    第一步,你需要在后台修改你所要显示的新闻数目: 第二步,你需要把这段代码加到你需要分页的列表里边 代码: <%=config.TopAd%><asp:Literal id=" ...

  2. Javassist之使用字节码在运行时生成新的类 01

    介绍 Javassist是一个开源的分析.编辑和创建Java字节码的类库.是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的.它已加入了开放源代码JBoss 应用 ...

  3. Lodop打印旋转180度 倒着打

    方法1:打印出来后,直接把纸张倒过来.如果本身是白纸,打印机出纸内容是倒着的,可以打出来后手动倒着把纸张正过来.如果本身不是白纸,需要打印的纸张上有背景,调整进纸方向.(如果是卷纸,卷纸背景是反的,查 ...

  4. Vivado安装、生成bit文件及烧录FPGA的简要流程

    https://wenku.baidu.com/view/0294cbb3bb4cf7ec4bfed01a.html

  5. JdbcTemplate的运用 (也是数据源的一种)

  6. 在GitHub上读大学:涵盖清华,北大,浙大等大学课程

    来自多位GitHub网友在GitHub分享的几组学习课程项目, 学习课程包含清华,北大,浙大,中科大,上海交大, 等中国多所名校的英语,AI高数,人工智能等课程以及一些讲义考题. 如果你想了解这些大学 ...

  7. [51Nod 1584] 加权约数和

    Description 在整理以前的试题时,他发现了这样一道题目:"求 \(\sum\sigma(i)\),其中 \(1≤i≤N\),\(σ(i)\) 表示 \(i\) 的约数之和.&quo ...

  8. 「AC自动机」学习笔记

    AC自动机(Aho-Corasick Automaton),虽然不能够帮你自动AC,但是真的还是非常神奇的一个数据结构.AC自动机用来处理多模式串匹配问题,可以看做是KMP(单模式串匹配问题)的升级版 ...

  9. HBase 清空表数据

    public int clearTableByTableName(String tableName) throws Exception { logger.debug("======InitH ...

  10. 【XSY2332】Randomized Binary Search Tree 概率DP FFT

    题目描述 \(\forall 0\leq i<n\),求有多少棵\(n\)个点,权值和优先级完全随机的treap的树高为\(i\). \(n\leq 30000\) 题解 设\(f_{i,j}\ ...