通过对源码各个模块的分析,可以帮助我们对macaca的整体构成有一个基础的认识。macaca已经开源,相关的源码在对应的github上都可以下载:
为了方便大家查看,宝宝费了好大劲画了下面这张图(觉得不错的给个赞吧):
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicGcq5ycpRXMzBjelFjMqNGahN3MwgTahZWM3d2NwYTY1YjY28CXldmchx2Lc52YucWbpFmbpNnLyc3dvw1LcpDc0RHaiojIsJye.jpg)
macaca提供的命令行工具
<code>$macaca server</code> 启动server
<code>$macaca server --verbose</code> 启动server并打印详细日志
<code>$macaca doctor</code> 检验当前macaca环境配置
macaca是按照经典的server-client设计模式进行设计的,也就是我们常说的c/s架构。webdriver-server部分便充当了server这部分的角色,他的职责就是等待client发送请求并做出响应。
client端简单来讲就是我们的测试代码,我们测试代码中的一些行为,比如控件查找、点击等,这些行为以http请求的方式发送给server,server接收请求,并执行相应操作,并在response中返回执行状态、返回值等信息。
也正是基于这种经典的c/s架构,所以client端具有跨语言的特点,macaca-wd,wd.java,wd.py分别是macaca团队针对js java 以及python的封装,只要能保证client端按照指定的要求发送http请求,任意语言都可以。
自动化要在不同的平台上跑,需要有对应平台的驱动,这部分驱动接收到来自server的操作命令,驱动各自平台的底层完成对应的操作。
macaca针对安卓平台的驱动集合
macaca-android 安卓驱动
macaca-adb 封装了安卓的adb命令,来实现一些adb的操作,比如安装、卸载、启动app、获取设备列表这些操作
android-unicode 经过封装后的输入法,解决中文输入的问题
uiautomator-client 将来自server的操作指令转换为uiautomator可以识别的指令,驱动uiautomator完成对应的操作
android-performance 用于自动化测试安卓性能相关的支持
macaca针对ios平台的驱动集合
macaca-ios ios驱动
xctest-client 同安卓的uiautomator-client异曲同工,对xcuitest的封装,将来自server的操作指令转换为xcuitest可以识别的指令,驱动xcuitest完成对应的操作
ios-simulator 用于对ios模拟器的支持,可以通过模拟器运行用例
remote-debug 用于远程调试
macaca针对hybrid的驱动集合。
macaca-chrome web测试驱动
macaca-chromedriver 驱动chrome浏览器
ios-webkit-debug-proxy 适用于ios平台对webview的调试
macaca针对pc端网页应用的支持
macaca-electron
了解了macaca的组成模块以及他们各自的作用,下面我们看一下各个模块是如何组装起来实现自动化测试流程的,宝宝同样费了很大劲画了一张图如下:
源码克隆到本地并配置好macaca相关环境后,我们来执行一次用例:
从这一步打印的信息我们可以看到,这一步实际上执行的是流程图中第一步的操作,启动server,建立连接,然后server返回所连接的ip以及端口号,因为我们是本地跑,所以ip实际上是本机的ip地址
以sampletest为例,右键执行junittest,稍作等待,就会看到系统自动启动了ios的模拟器并跑起来了用例。执行过程中的某个截图如下:
首先我们来看一下对应用例启动的client端核心代码:
在这段代码中,我们做的工作是根据不同的平台设置用例的一些基础启动信息,包含平台类型、安装包地址、设备id、是否覆盖安装等参数,设置完成后,通过driver.initdriver(desiredcapabilities)这个操作启动driver,这个过程便会按照流程图中的第二个步骤发送http请求,server会接收到这个请求并创建一个session,在这次的用例执行中,所有的操作都会基于这个session进行,来看一下针对这个操作控制台所打印的信息(为方便突出主要过程省略了部分无关日志):
经过如上步骤后,连接便已经成功建立了,下一步再分析一下一个具体操作,以登录为例,对应的client端的代码如下:
(因为框架层封装了一些操作,所以代码看上去比较少,具体的控件查找部分看不到,有需要详细了解的可以研究源码)
对应登录按钮的查询操作,我们会在控制台上看到如下的日志:
在上面的日志中我们可以看到,当我们查找登录按钮的时候,client发送了一个http请求给server,请求的操作是element(这个表示控件查找),参数是{"using":"name","value":"login"},这是告诉server我们要找的这个控件的name属性是login,server收到这个请求,通过router路由转发给ios的驱动(在启动driver的时候已经设置的平台类型,因此这里能知道找ios),ios驱动收到请求驱动xcuitest框架对模拟器上的目标app执行对应的控件查找操作,得到response后原路返回给client,这样就完成了一次请求的完整的生命周期。
如上简单总结了macaca的基础原理,提供一个小窍门是大家可以对照控制台输出与文章中的流程图一一对应,这样就能大体了解整个流程的数据流向,从而就能参透macaca的基础原理了。个人水平有限,如有不当,欢迎指正。
后面会陆续放出自己在实践中的其他心得与经验,敬请期待,也欢迎大家交流讨论。