ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Appium 工作原理全解:WebDriver 协议、Driver 机制与扩展生态

Appium 工作原理全解:WebDriver 协议、Driver 机制与扩展生态 Appium 工作原理全解WebDriver 协议、Driver 机制与扩展生态【免费下载链接】appiumCross-platform automation framework for all kinds of apps, built on top of the W3C WebDriver protocol项目地址: https://gitcode.com/GitHub_Trending/ap/appiumAppium 是一个开源的多应用平台 UI 自动化框架其核心设计哲学是无论目标平台是 iOS、Android 还是其他设备开发者都能用一套统一的标准 API编写自动化代码。本文以packages/appium/docs/ja/intro/appium.md及对应的英文/中文介绍页为核心骨架结合本仓库源码深入拆解 Appium 的四大关键设计WebDriver 协议选型、Driver 可插拔机制、HTTP 客户端-服务器架构以及驱动/插件扩展生态。读完本文你将完整理解Appium 是如何工作的并知道每条自动化命令从客户端发出到平台执行之间发生了什么。一、总览四个驱动 Appium 的关键问题正如 介绍页 所述Appium 2 的发布使其确立了三个主要目标在跨平台的标准 API 之下提供平台特定的自动化能力允许从任何编程语言轻松访问这套 API为社区提供便利的工具使其能够开发 Appium 扩展。围绕这些目标官方文档提出了一连串环环相扣的问题而这些问题正是理解整个框架的钥匙单一、统一的 API 应该选什么如何把这套 API 映射到特定平台的自动化行为如何让这套 API 被多种主流编程语言调用更进一步iOS/Android 之外还有大量平台如何为所有平台实现自动化接下来的每一节分别对应 Appium 给出的答案采用 W3C WebDriver 规范、引入可插拔的 Driver 模块、把 Appium 做成 HTTP 服务器并配套各语言客户端、把 Appium 打造成可被社区扩展的开放平台。二、Appium 的 API 选择为什么是 WebDriver 规范2.1 继承 Selenium 的遗产Appium 之所以选定 WebDriver 规范作为 API与其前驱 Selenium 的长期沉淀密不可分。Selenium 项目致力于 Web 浏览器的 UI 自动化可以看作 Appium 目标的一个子集在演进过程中Selenium及其合并的 WebDriver 项目形成了一套相对稳定的浏览器自动化 API。随后Selenium 与各浏览器厂商及 W3C 标准组织合作将这套 API 正式确立为浏览器自动化标准——WebDriver 规范。如今所有主流浏览器都直接实现了与 WebDriver 规范一致的自动化能力甚至不需要 Selenium 团队再维护任何执行实际自动化的软件。Appium 最初的目标是为移动应用iOS 与 Android建立自动化标准。它本可以另起炉灶发明新东西但为了保持标准的统一性最终决定直接采用 WebDriver 规范作为自己的 API。事实依据是虽然网站交互与移动原生应用交互并非完全一致考虑遥控器控制的电视平台差异更大但绝大多数软件 UI 是相似的——WebDriver 规范提供的自动化原语查找元素、与元素交互、加载页面或屏幕等可以或多或少地映射到任何平台。历史注脚从技术上说Appium 最初编写时使用的是比 WebDriver 规范更早的JSON Wire ProtocolJSONWP。此后 Appium 一直随 W3C 规范共同演化如今完全符合 W3C 规范。仓库中 base-driver 的协议层 同时保留了 W3C 与 JSONWP 的错误码转换逻辑如errorFromMJSONWPStatusCode、errorFromW3CJsonCode、determineProtocol正是这段历史在代码里的体现。2.2 使用标准规范时的两个注意事项采用标准并不意味着无条件全盘照搬。文档明确指出了两个 caveat部分命令可能在特定平台不受支持例如在原生移动应用自动化场景中获取或设置 cookie 就是不可能的可能支持超出 WebDriver 命令列表的自动化行为任何这类命令都会以合法且符合规范的扩展形式出现即 WebDriver 规范内置的可扩展性。Appium 正是通过实现 WebDriver 协议这一方式引入了统一的 UI 自动化接口。仓库中 appium.ts 的AppiumDriver类直接继承自DriverCore并持有desiredCapConstraints要求automationName与platformName两个 capability 必须存在这就是协议入口在代码层面的落脚点。三、平台自动化行为可插拔的 Driver 机制3.1 Appium 本身不做平台自动化下一个关键问题是Appium 如何把 WebDriver 协议映射到众多平台的自动化行为答案出人意料——严格来说Appium 自己不做这件事。它把这个责任交给一种称为 AppiumDriver的软件模块。Driver 本质上是 Appium 的可插拔模块赋予 Appium 自动化某个特定平台或一组平台的能力。最终一个 Driver 的职责就是实现一个代表 WebDriver 协议的 Appium 内部接口至于如何实现完全由 Driver 自己根据其在特定平台上的自动化策略决定。通常Driver 会依赖平台原生的自动化技术来完成协议到库调用的转换。最典型的例子是 iOSApple 官方维护的 iOS 自动化技术叫 XCUITest因此 Appium 中支持 iOS 自动化的驱动就叫 XCUITest Driver——它本质上就是把 WebDriver 协议转换成 XCUITest 库调用。从本仓库源码可以看到Appium 官方登记了一系列知名驱动定义在 constants.ts 的KNOWN_DRIVERS中涵盖三类类别驱动名manifest keynpm 包移动平台uiautomator2appium-uiautomator2-driverAndroid移动平台xcuitestappium-xcuitest-driveriOS移动平台espressoappium-espresso-driverAndroid桌面平台mac2appium-mac2-driver桌面平台windowsappium-windows-driver桌面浏览器safari/gecko/chromiumappium-safari-driver/appium-geckodriver/appium-chromium-driver3.2 源码视角Driver 如何被选中并加载Driver 的匹配与加载逻辑集中在 driver-config.ts 的DriverConfig.findMatchingDriver方法中。其工作流程非常直观校验platformName与automationName两个 capability 必须存在遍历已安装驱动根据automationName大小写不敏感与platformNames列表做双重匹配匹配成功后动态加载驱动包的入口文件requireAsync返回驱动类、版本与名称若匹配失败会提示用户是否安装了支持这些 capability 的驱动可运行appium driver list --installed查看。随后在 appium.ts 的 createSession 中Appium 扮演伞形驱动umbrella driver的角色它持有全局会话表sessions根据 capability 挑选出具体的内层驱动inner driver并实例化然后调用内层驱动的createSession完成会话创建再把sessionId注册进主会话列表。换句话说Appium 服务器的会话管理、路由分发由伞形驱动负责而真正的平台自动化由内层驱动负责——这正是严格来说 Appium 不做平台自动化这一表述的源码级证据。3.3 用专属 CLI 管理驱动由于不同平台的驱动在构建与使用上差异巨大Appium 允许你只安装自动化任务真正需要的驱动并且为此提供了专属的命令行工具。CLI 参数定义见 cli/args.ts驱动与插件共用一套子命令模型主要包括appium driver list [--installed] [--updates] [--verbose]列出可用/已安装驱动可附带更新信息appium driver install name安装驱动支持--source npm|git|github|local与--package参数appium driver uninstall name卸载驱动appium driver update name|installed [--unsafe]更新驱动installed表示全部更新--unsafe允许包含可能不兼容的主版本升级appium driver run name [scriptName]运行驱动包package.json中appium.scripts声明的脚本appium driver doctor name对驱动运行环境做体检。这些子命令的底层实现位于 extension-command.tsExtensionCliCommand抽象类把list/install/uninstall/update/run/doctor统一映射为可执行方法安装走 npm同时校验package.json中name、version、appium字段的完整性最终把扩展元数据写入extensions.yaml清单见下文第五节。四、通用编程语言访问HTTP 客户端-服务器架构4.1 为什么不做成 Node.js 库Appium 本质上是一个 Node.js 程序理论上完全可以把 Appium 与驱动当作库导入自己的 Node.js 项目。但这样做无法满足为任何主流编程语言使用者提供自动化能力的目标。幸运的是Appium 站在了 Selenium 的肩膀上——WebDriver 规范本质上是一个基于 HTTP 的协议天生设计为通过网络使用而不是在单个程序的内存中调用。4.2 客户端-服务器分离带来的收益这种客户端-服务器架构的核心好处是自动化实现者执行自动化的一端即服务器可以与自动化运行者定义自动化步骤的一端即客户端完全分离。所有困难的部分如何在给定平台上真正执行自动化集中在服务器端解决而客户端库则可以是瘦的——用任何语言编写的、把 HTTP 请求按该语言习惯编码出来的简单封装。只要目标语言存在高级 HTTP 库编写一个基础 HTTP 客户端就能相对轻松地为该语言引入 Appium/WebDriver 能力。对使用者而言有几点重要结论原文明确列出Appium 是一个 HTTP 服务器只要你想使用它做自动化它就必须以进程形式在某个计算机上持续运行并且对运行自动化的那台计算机无论是本机还是世界另一端在网络上可达通常需要配合 Appium Client 使用除非你想手写原始 HTTP 调用或用 cURL否则自动化会用到所选语言的 Appium Client。每个客户端的目标都是封装 WebDriver 协议让你以符合语言习惯的对象和方法工作而无需关心协议细节服务器与客户端无需在同一台计算机上只需要能通过网络从客户端向服务器发送 HTTP 请求即可。这一点极大方便了云服务商的使用——他们可以托管 Appium 服务器及相关的驱动和设备你只需把客户端脚本指向其安全端点。仓库中 HTTP 服务器的实现在 base-driver 的 express 服务server()函数基于 Express 构建支持自定义端口、hostname、basePath、CORS、WebSocket 升级等routeConfiguringFunction负责把 WebDriver 路由注册到 Express 应用上。此外Appium 还在 appium.ts 中实现了 WebDriver 规范定义的GET /status端点返回ready状态与构建信息——这既是一个心跳探测点也体现了对规范的逐条落实。4.3 自动化的目的不限于测试文档特别强调以上这一切都是关于自动化本身而非测试。如果你想用 Appium 做测试还需要借助测试运行器、测试框架等与 Appium 无关的工具。Appium 通用可访问性的好处之一正是能与任何你认为合适的工具集良好协作。五、Appium 的巨大范围驱动与插件的开放生态5.1 愿景与现实的差距Appium 的愿景——在单一 API 下自动化一切——远超核心维护团队能独立实现的范围。因此 Appium 的答案是把社区赋能为在 Appium 之上开发的平台这就是所谓的 Appium 生态系统ecosystem。官方团队只亲自维护少数驱动如前面提到的 XCUITest Driver但自 Appium 2 起团队提供了让社区加入愿景的工具任何人都可以创建 Driver只需创建一个符合约定、实现 WebDriver 协议任意子|超集的 Node.js 模块。由于协议细节已被抽象且有大量辅助库正是驱动 Appium 官方驱动的那批库可用创建驱动通常只需很少代码共享 Driver 很容易通过 Appium driver CLI 即可分发没有中央权威——任何人都可以公开或私下、免费或收费地分享驱动驱动可以是开源或闭源的。5.2 Plugin改变 Appium 工作方式的模块作为自动化工具的流行Appium 有大量机会与各种工具和服务集成核心团队永远没有时间实现所有功能想法。因此 Appium 2 发布了插件plugin系统任何人都能构建和分享改变 Appium 工作方式的模块。与驱动通过 driver CLI 分享相平行插件通过对应的 Plugin CLI 发布与消费。插件的想象空间几乎没有限制例如本仓库中就包含images-plugin它让 Appium 能基于模板图片查找并交互屏幕区域。仓库 constants.ts 中的KNOWN_PLUGINS列出了官方认可的一组插件execute-driver对应appium/execute-driver-plugin、imagesappium/images-plugin、inspector、relaxed-caps、storage、universal-xml。你在本仓库的packages/目录下可以看到这些插件的完整实现例如 images-plugin、execute-driver-plugin、relaxed-caps-plugin 等可作为学习插件开发的真实范本。5.3 源码视角manifest 与扩展生命周期驱动与插件之所以能即装即用背后是 manifest.ts 实现的清单机制扩展安装信息被持久化到APPIUM_HOME下的extensions.yaml其结构包含drivers、plugins两个分区与schemaRev版本号当前为 4。Manifest.read()负责读取 YAML、必要时执行 schema 迁移manifest-migrations.ts并扫描node_modules中带appium字段的包自动同步清单extension-config.ts 的ExtensionConfig则统一负责扩展的校验版本、包名、mainClass、schema、安装类型识别npm/local/github/git/dev与动态加载。整个机制保证了驱动与插件是真正的一等公民Appium 服务器启动时即可感知并加载它们。六、把一切串起来一次自动化请求的完整旅程结合 appium.ts 的executeCommand实现可以还原一次典型 WebDriver 请求的完整调用链客户端任意语言的 Appium Client把命令封装为 HTTP 请求发送到 Appium 服务器的 WebDriver 路由如POST /session、GET /session/:id/source等路由定义见 protocol 路由 导出的METHOD_MAP/routeToCommandName服务器收到请求后由伞形驱动AppiumDriver.executeCommand分发GET /status这类免会话命令由伞形驱动自己处理deleteSession等命令也在伞形驱动层执行其余会话命令则转交给该 session 对应的内层平台驱动在转交前后注册了该命令的插件会被依次包裹成调用链wrapCommandWithPlugins每个插件都可以选择执行自己的处理器、调用next()放行或直接终结命令——这正是插件可以改变 Appium 工作方式的运行时体现内层驱动把协议命令翻译成平台自动化技术调用如 iOS 上的 XCUITest 库调用、Android 上的 UiAutomator2 调用执行完毕后沿原路把结果封装为 WebDriver 规范的响应返回给客户端。由此可以看到Appium 的全部设计目标——标准 API、跨平台、多语言、可扩展——都落到了同一条清晰的分层链路上标准协议负责统一Driver 负责平台差异HTTP 负责语言无关插件负责生态延伸。七、继续深入想了解 Driver 的具体工作机制与开发方法可阅读 Driver 介绍 与 驱动生态概览想了解各语言客户端如何封装协议见 客户端介绍想学习插件系统的完整用法见 插件生态概览 与 扩展 CLI 参考想在代码层面把玩扩展生命周期可重点阅读 manifest.ts、extension-config.ts 与 extension-command.ts。一句话总结Appium 是一个可扩展的、面向潜在一切界面的统一 UI 自动化接口——它以 WebDriver 规范为 API、以 Driver 承载平台能力、以 HTTP 实现语言无关、以插件系统拥抱社区四者共同构成了Appium 如何工作的完整答案。【免费下载链接】appiumCross-platform automation framework for all kinds of apps, built on top of the W3C WebDriver protocol项目地址: https://gitcode.com/GitHub_Trending/ap/appium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表