源代码层面分析Appium-inspector工作原理

Appium-inspector功能

Appium Inspector 基于 Appium 框架,Appium 是一个开源工具,用于自动化移动应用(iOS 和 Android)和桌面应用(Windows 和 Mac)。Appium 采用了客户端-服务器架构,允许用户通过客户端(例如 Appium Inspector)与 Appium 服务器通信,以自动化测试应用程序。主要用这个工具来查找获取元素的locator,提升mobile UI自动化测试效率。

Appium-inspector的界面如下图所示,在界面上可以点击app页面元素,左边会显示被选择元素的selector,在app source的具体位置等信息。

Appium-inspector工作原理

Appium-inspector的工作流程大致可以分为如下四个部分
连接移动设备或模拟器:Appium Inspector 连接到目标移动设备或模拟器。可以是物理设备,也可以是虚拟设备(模拟器或仿真器)。
启动移动应用:Appium 服务器接收客户端(Appium Inspector)的指令,通过相应的驱动(如 uiautomator2 驱动用于 Android,XCUITest 驱动用于 iOS),启动目标移动应用。

获取应用页面源代码:一旦应用启动,Appium 服务器通过驱动与移动设备或模拟器通信,获取当前页面的源代码(DOM 树),包括所有 UI 元素及其属性。这个页面源代码通常以 XML 格式表示。
展示 UI 元素:Appium Inspector 将获取到的页面源代码解析并展示在图形界面上。用户可以在 Appium Inspector 中看到当前应用页面的结构、元素的层次关系,以及每个元素的属性(如 resource-id、class、text 等)。
生成 Locator:用户在 Appium Inspector 中可以选择某个 UI 元素,Appium Inspector 会根据该元素的属性生成唯一的定位符(Locator)。这些 Locator 可以用来在自动化脚本中定位和操作该元素。常见的 Locator 类型包括:ID、XPath、Class Name、Accessibility ID 等。

Appium-inspector如何显示mobile app UI

在appium inspector上面,可以加载显示mobile app应用页面,这个是如何实现的呢?实际appium inspector是通过截图来显示app页面UI的,实现这个过程主要有四个步骤

截图获取: Appium Inspector使用Appium Server通过WebDriver协议与移动设备建立连接。一旦连接建立,Inspector会向设备发送命令以获取当前应用的屏幕截图。

截图传输: 设备收到命令后,会执行截图操作,并将截图数据传输回Appium Server。这通常是以base64编码的图像数据的形式返回。

解码和展示: Appium Server接收到截图数据后,会对其进行解码,并在Inspector界面中展示。Inspector本身会使用相关的图像处理技术,如将base64编码的图像数据解析为可见的图像。

图像渲染: 解码后的图像在Inspector界面中进行渲染,以显示移动应用的当前界面。这个过程涉及将图像数据转换为可视化的UI元素,通常以实时或者轮询的方式更新截图以显示最新状态。

当用appium-inspector连接到appium server时,可以在appium server的日志中看到如下信息,可以看到调用了appium server的接口获取screenshot信息和page source信息。screenshot就是用来显示mobile app UI的。

Appium-inspector如何生成selector

当鼠标hover到某个元素时,appium inspector会设置元素的x,y坐标信息。有了坐标信息,就可以发送给appium server来获取页面元素信息。(需要补充修改)

Appium-inspector源码阅读

下图是appium-inspector source code,component里面是用react写各个自定义组件,这些组件会组合到containers下面的InspectorPage.js和SessionPage.js中,其中SessionPage.js及时appium-inspector连接信息输入的界面,InspectorPage.js就是连接成功后显示source page,locator等信息的的界面。另外,这里使用了react reducers技术,在 React 应用中,useReducer 钩子是一种处理复杂状态逻辑的方式,特别是当组件状态由多个子值组成,或者当状态逻辑需要根据多种不同的动作进行更改时。

以reducers目录下Inspector.js为例,接受action.type,来更新state信息。

以action目录下的Inspector.js为例,文件里面定义了很多方法,主要是通过dispatch来分发动作。

像获取整个页面的pageSource,screenshot等,是call appium server的api来获取的,这些需要与appium server进行交互的部分,都封装在callClientMethod方法里,这个方法也定义在action/Inspector.js文件中。

除了上面的一些关键source code,当用户点击页面的某个element的时候,会在appium-inspector中显示生成的selector,这个是如何实现的呢?在utils目录下有个locator-generation.js文件,里面有getSuggestedLocactor方法,里面调用了getSimpleSuggestedLocators和getComplexSuggestedLocators方法,再将获取的locator进行对比选取合理的locator。

SimpleSuggestedLocators方法主要是看元素信息中是否有content-desc,id,resource-id等信息,如果有这些信息,就用这些信息来生成locator。

ComplexSuggestedLocators方法,主要是使用'-ios class chain','-android uiautomator'等来生成定义页面元素的locator。

上面生成locator的前提是要给出选定element的相关信息,从appium-inspector中下载source page,如下图所示,source page中除了有元素的content-desc等信息外,还有个关键信息是bounds,也就是元素的坐标信息。当鼠标选中某个element的时候,可以计算得到element的坐标信息,再根据这个坐标信息从source page中获取到对应的目标元素信息。那appium-inspector是什么时候计算所选元素的坐标信息的呢?

在component目录下的Screenshot.jsx文件中,有个handleMouseMove的方法,可以看到,当鼠标移动的时候,这里会调用setX,setY来设置坐标信息。

以上就是Appium-inspector源码部分解读,可以看到Appium源码理解可以分为下面7部分

**1:**使用react来构建appium-inspector的UI,主要保卡session页面和inspector页面。

**2:**使用了react的reducer来管理复杂的状态信息,对于涉及异步调用的部分,还使用了redux thunk。

**3:**需要与appium server交互的部分,都封装在clientMethod中。

**4:**inspector界面显示的app UI是通过调用appium server api,获取到app的截图信息,然后通过截图显示来实现app UI展示的。

**5:**inspector界面的page source也是调用appium server的api获取的。

**6:**获取的page source里面包含每个页面元素的坐标信息,当鼠标move到某个元素上面时,会设置元素的x,y坐标信息,这样当选中某个元素的时候,可以通过坐标信息,获取目标元素在page source中的所有信息

**7:**获取到元素信息后,封装了一些方法来生成locator,主要包括简单locator生成和复杂locator生成。实际只通过坐标获取到当前元素属性信息,还无法直接生成所有的locator,在source code的utils目录下有个source-parsing文件,即把xml格式的page source信息转换成JSON格式的信息,有了JSON格式的数据,才能通过当前元素查找这个元素的父亲元素,从而生成完善的locator信息,生成locator信息后,还可以调用appium-server的api确定这个locator是否是正确和唯一的。

以下图为例,当选中左边的username input输入框的时候,右边的locator有两种方式,第一种是通过id查找element,第二种是通过xpath查找element。当确定了selector后,appium-inspector会调用appium server的api来确认是否能查找到元素。

如下图所示,是inspector调用apppium server的api的截图信息,当输入id的信息,调用接口时,返回了'no such element',当输入xpath信息,调用接口,返回的element的信息,返回的状态码也是200,说明匹配到元素。

xml格式转换成json格式

Appium-inspector中,当获取到xml格式的page source后,还调用了util里面的parsing方法将xml格式转换成json格式的page source,source code内容如下图所示:

这个方法的作用就是将xml格式的page source转换成JSON格式,转换后,就可以检索获取当前element的层级信息了,便于生成xpath信息。假设输入的xml格式的source如下图所示:

调用方法后,生成的JSON格式的内容如下图所示:可以看到,在json格式数据中,可以通过path信息,计算出所有元素之间的层级关系。

复制代码
{
  "children": [
    {
      "children": [
        {
          "children": [],
          "tagName": "title",
          "attributes": {
            "lang": "en"
          },
          "path": "0.0"
        },
        {
          "children": [],
          "tagName": "author",
          "attributes": {},
          "path": "0.1"
        },
        {
          "children": [],
          "tagName": "year",
          "attributes": {},
          "path": "0.2"
        },
        {
          "children": [],
          "tagName": "price",
          "attributes": {},
          "path": "0.3"
        }
      ],
      "tagName": "book",
      "attributes": {
        "category": "children"
      },
      "path": "0"
    },
    {
      "children": [
        {
          "children": [],
          "tagName": "title",
          "attributes": {
            "lang": "en"
          },
          "path": "1.0"
        },
        {
          "children": [],
          "tagName": "author",
          "attributes": {},
          "path": "1.1"
        },
        {
          "children": [],
          "tagName": "year",
          "attributes": {},
          "path": "1.2"
        },
        {
          "children": [],
          "tagName": "price",
          "attributes": {},
          "path": "1.3"
        }
      ],
      "tagName": "book",
      "attributes": {
        "category": "web"
      },
      "path": "1"
    }
  ],
  "tagName": "bookstore",
  "attributes": {},
  "path": ""
}

以上就是整个appium-inspector实现原理的梳理和总结。

相关推荐
niuniu_6662 天前
安全性测试(Security Testing)
测试工具·单元测试·appium·测试·安全性测试
niuniu_6663 天前
appium应用测试场景
功能测试·selenium·测试工具·appium·测试
suimeng63 天前
Appium中元素定位的注意点
appium
suimeng65 天前
Appium中元素定位之一个元素定位API
appium
一禅(OneZen)6 天前
【L2.第二章】Appium 元素定位工具
python·selenium·appium·自动化·web
suimeng66 天前
Appium中元素定位之一组元素定位API
appium
开水好喝8 天前
Appium Inspector使用教程
appium
曦若(xi ruo)17 天前
自动化APP测试APPium的元素等待
运维·appium·自动化
qq_白羊座20 天前
UI自动化:poium测试库使用文档
python·selenium·ui·appium
fantasy_421 天前
Appium高级操作--ActionChains类、Toast元素识别、Hybrid App操作、手机系统API的操作
android·python·appium·自动化