下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

详解Appium Android Bootstrap源码之启动运行教程

作者:课课家教育     来源: http://www.kokojia.com点击数:1425发布时间: 2016-04-19 14:32:40

标签: Android Bootstrap安卓源码Bootstrap

        在学习Bootstrap源码之启动运行之前,先来学习一下appium,Appium是一个移动端的自动化框架,可用于测试原生应用,移动网页应用和混合型应用,且是跨平台的。可用于IOS和Android以及firefox的操作系统。原生的应用是指用android或ios的sdk编写的应用,移动网页应用是指网页应用,类似于ios中safari应用或者Chrome应用或者类浏览器的应用。混合应用是指一种包裹webview的应用,原生应用于网页内容交互性的应用。重要的是Appium是跨平台的,何为跨平台,意思就是可以针对不同的平台用一套api来编写测试用例。

详解Appium Android Bootstrap源码之启动运行教程_Android Bootstrap_安卓源码_Bootstrap_课课家

      通过前面的两篇文章《Appium Android Bootstrap源码分析之控件AndroidElement》和《Appium Android Bootstrap源码分析之命令解析执行》我们了解到了Appium从pc端发送过来的命令是如何定位到命令相关的控件以及如何解析执行该命令。那么我们剩下的问题就是bootstrap是怎么启动运行的,我们会通过本篇文章的分析来阐述这个问题,以及把之前学习的相关的类给串起来看它们是怎么互动的。

  1.启动方式

  Bootstrap的启动是由Appium从pc端通过adb发送命令来控制的:

  从上面的调试信息我们可以看到AppiumBootstrap.jar是通过uiautomator这个命令作为一个测试包,它指定的测试类是io.appium.android.bootstrap.Bootstrap这个类。大家如果看了本人之前的文章《UIAutomator源码分析之启动和运行》的话应该对uiautomator的启动原理很熟悉了。

  启动命令:uiautomator runtest AppiumBootstrap.jar -c io.appium.android.bootstrap.Bootstrap

  那么我们进入到Bootstrap这个类看下它是怎么实现的:

  从代码中可以看到,这个类是继承与UiAutomatorTestCase的,这样它就能被uiautomator作为测试用例类来执行了。

  这个类只有一个测试方法testRunServer,所有事情发生的源头就在这里:

  创建一个socket服务器并监听4724端口,Appium在pc端就是通过连接这么端口来把命令发送过来的

  循环监听获取Appium从pc端发送过来的命令数据,然后进行相应的处理

  2. 创建socket服务器并初始化Action到CommandHandler的映射

  我们先看下SocketServer的构造函数:

  它做的第一个事情是先去创建一个AndroidCommandExecutor的实例,大家应该还记得上一篇文章说到的这个类里面保存了一个静态的很重要的action到命令处理类CommandHandler的实例的映射表吧?如果没有看过的请先去看下。

  建立好这个静态映射表之后,构造函数下一步就似乎去创建一个ServerSocket来给Appium从PC端进行连接通信了。

  3.获取并执行Appium命令数据

  Bootstrap在创建好socket服务器后,下一步就是调用SocketServer的listenForever的方法去循环读取处理appium发送出来的命令数据了:

  首先调用server.accept去接受appium的连接请求,连接上后就去初始化用于读取socket的BufferedReader和BufferredWriter这两个类的实例,最后进入到handleClicentData来进行真正的数据读取和处理

  通过刚才建立的socket读取对象去读取appium发送过来的数据

  把获得的的json命令字串发送给getCommand方法来实例化我们的AndroidCommand这个类,然后我们就可以通过这个解析器来获得我们想要的json命令项了

  调用runCommand方法来使用我们在第二节构造ServerSocket的时候实例化的AndroidComandExecutor对象的execute方法来执行命令,这个命令最终会通过上面的AndroidCommand这个命令解析器的实例来获得appium发送过来的action,然后根据map调用对应的CommandHandler来处理命令。而如果命令是控件相关的,比如获取一个控件的文本信息GetText,处理命令类又会继续去AndroidElementHash维护的控件哈希表获取到对应的控件,然后再通过UiObject把命令发送出去等等..不清楚的请查看上篇文章[java

  通过上面建立的socket写对象把返回信息写到socket发送给appium

  4.控件是如何加入到控件哈希表的

  大家可能奇怪,怎么整个运行流程都说完了,提到了怎么去控件哈希表获取一个控件,但怎么没有看到把一个控件加入到控件哈希表呢?其实大家写脚本的时候给一个控件发送click等命令的时候都需要先取找到这个控件,比如:

  这里的finElement其实就是一个命令,获取控件并存放到控件哈希表就是由它对应的CommandHandler实现类Find来完成的。

  可以看到appium过来的命令包含几项,有我们之间碰到过的,也有没有碰到过的:

  cmd:指定是一个action

  action:指定这个action是一个find命令

  params

  strategy:指定选择子的策略是根据空间名name来进行查找

  selector: 指定选择子的内容是"Add note"

  context: 指定空间哈希表中目标控件的键值id,这里为空,因为该控件我们之前没有用过

  multiple: 表明你脚本代码用的是findElements还是findElement,是否要获取多个控件

  Find重写父类的execute方法有点长,我们把它breakdown一步一步来看.

  第一步:获得控件的选择子策略,以便跟着通过该策略来建立uiautomator的UiSelector

  appium支持的策略有以下几种,这其实在我们写脚本中findElement经常会指定:

  第二步:获取appium发过来的选择子的其他信息如内容,控件哈希表键值,是否是符合选择子等

  第三步,在获得一样的选择子的信息后,就可以根据该选择子信息建立真正的UiSelector选择子列表了,这里用列表应该是考虑到今后的复合选择子的情况,当前我们并没有用到,整个列表只会有一个UiSelector选择子

  第四步:组建好选择子UiSelector列表后,Find会根据你是findElement还是findElement,也就是说是查找一个控件还是多个控件来查找控件,但是无论是多个还是一个,最终都是调用fetchElement这个方法来取查找的

  而fetchElement最终调用的控件哈希表类的getElements:

  AndroidElementHash的这个方法我们在前一篇文章《Appium Android Bootstrap源码分析之控件AndroidElement》已经分析过,我们今天再来温习一下.

  从Appium发过来的控件查找命令大方向上分两类:

  1. 直接基于Appium Driver来查找,这种情况下appium发过来的json命令是不包含控件哈希表的键值信息的

  2. 基于父控件查找:

  以上的脚本会先尝试找到Note1这个日记的父控件ListView,并把这个控件保存到控件哈希表,然后再根据父控件的哈希表键值以及子控件的选择子找到想要的Note1:

  AndroidElementHash的这个getElement命令要做的事情就是针对这两点来根据不同情况获得目标控件的

  如果是第1种情况就直接通过选择子构建UiObject对象,然后通过addElement把UiObject对象转换成AndroidElement对象保存到控件哈希表

  如果是第2种情况就先根据appium传过来的控件哈希表键值获得父控件,再通过子控件的选择子在父控件的基础上查找到目标UiObject控件,最后跟上面一样把该控件通过addElement把UiObject控件转换成AndroidElement控件对象保存到控件哈希表

  以下就是把控件添加到控件哈希表的addElement方法

  5. 小结

  Appium的bootstrap这个jar包以及里面的o.appium.android.bootstrap.Bootstrap类是通过uiautomator作为一个uiautomator的测试包和测试方法类启动起来的

  Bootstrap测试类继承于uiautomator可以使用的UiAutomatorTestCase

  bootstrap会启动一个socket server并监听来自4724端口的appium的连接

  一旦appium连接上来,bootstrap就会不停的去获取该端口的appium发送过来的命令数据进行解析和执行处理,然后把结果写到该端口返回给appium

  bootstrap获取到appium过来的json字串命令后,会通过AndroidCommand这个命令解析器解析出命令action,然后通过AndroidCommandExecutor的action到CommandHandler的map把action映射到真正的命令处理类,这些类都是继承与CommandHandler的实现类,它们都要重写该父类的execute方法来最终通过UiObject,UiDevice或反射获得UiAutomator没有暴露出来的QueryController/InteractionController来把命令真正的在安卓系统中执行

  appium获取控件大概有两类,一类是直接通过Appium/Android Driver获得,这一种情况过来的appium查找json命令字串是没有带控件哈希表的控件键值的;另外一种是根据控件的父类控件在控件哈希表中的键值和子控件的选择子来获得,这种情况过来的appium查找json命令字串是既提供了父控件在控件哈希表的键值又提供了子控件的选择子的

  一旦获取到的控件在控件哈希表中不存在,就需要把这个AndroidElement控件添加到该哈希表里面。

      上文图文并茂加代码详细分析Appium Android Bootstrap源码之启动运行的相关内容,想要了解更多关于Android开发的知识,先一步步打好基础,本文也只是学习android开发知识的冰山一角。

赞(0)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程