域管自动化测试技术调研
现状问题
域管产品主要分为服务端和客户端,服务端为一个后台服务 Web
平台系统,客户端为分布的 UOS
机器。
域管测试用例中,大量的用例会涉及到服务端和客户端协同操作。
服务端方面
现有域管 AT
主要实现为单接口自动化测试,这类自动化测试相对简单,主要校验接口的入参和返回,但较多业务场景是复合接口的,由于没有可用的 API
接口文档,导致很多场景没办法做接口自动化。
因此经过评估,服务端复合接口场景的测试,将基于 Web UI
自动化实现。
客户端方面
客户端为分布式的安装 UOS
系统的机器,现有的域管 AT
只能通过 SSH
的方式控制客户端做一些简单的命令行操作,比较局限,无法实现控制客户端做一些复杂的 UI
功能上的操作。
要实现的效果
基于以上现有问题,域管自动化测试我们希望最终实现的效果是:
- 能控制服务端
Web
平台做复杂的UI
功能操作,最好能直接驱动系统自带的浏览器进行测试; - 能远程控制客户端,既能做简单的命令行的操作,也能做复杂的
UI
功能操作。
技术方案
域管用例涉及服务端和客户端穿插操作,底层功能实现大体也会分为两部分:Server(服务端)
、Client(客户端)
。
Server(服务端)
基于 Web UI
自动化测试,控制浏览器进行用例执行。YouQu
目前还没有接入 Web UI
测试功能,要接入此功能需要先对工具进行选型。
工具调研
市面上耳熟能详的可用于 Web UI
自动化测试工具:Selenium
、Cypress
、Puppeteer
、Playwright
;
咱们先初步排除掉一些明显不用的:
Cypress
,只支持JavaScript
,而我们自动化人员大多使用Python
对JavaScript
不熟悉,排除。Puppeteer
,只支持谷歌浏览器,格局没打开,官方不支持Python
,排除。
剩下 Selenium
、Playwright
,我们从一些方面做对比:
对比指标 | Selenium | Playwright |
---|---|---|
环境安装难度 | ✗ | ✔ |
运行速度 | ✗ | ✔ |
元素等待 | ✗ | ✔ |
智能定位 | ✗ | ✔ |
稳定性 | ✔ | ✔ |
文档 | ✔ | ✗ |
接口测试 | ✗ | ✔ |
总结:
Playwright
作为一个比较新的工具,在文档方便确实没有老牌的 Selenium
完善,特别是一些示例、方法的使用说明,都还不够好,甚至有些就没有说明,但基本的使用该有的都有。
除了文档方面,Playwright
几乎在各方面碾压 Selenium
,很明显 Playwright
以绝对优势获胜。
设计思路
浏览器对象
YouQu
框架提供灵活可配置的浏览器对象。
提供一个全局默认的对象:
page
,默认使用系统自带的浏览器进行测试,如果需要指定其他第三方的浏览器,提供配置项可以指定浏览器对应的路径。还需要提供一个对象:
native_page
,它使用Playwright
最新的Chromium
浏览器进行测试。
方法层
方法层按照 PO 设计思想对域管 Web 平台进行封装。
目录结构:
server
├── __init__.py
├── pages
│ ├── _base_page.py # 基类
│ ├── home_page.py # 首页类
│ ├── audit_page.py # 审计页面类
│ ├── ... # 其他页面类
│ └── __init__.py
└── udcp_page.py # 方法层统一出口
- 基类负责处理通用页面行为;
- 首页、终端、审计等其他页面类,封装各自页面的元素定位和操作方法;
- 方法唯一出口用于集成所有的页面类,统一出口提供给上层用例调用。
断言方法
YouQu
框架统一提供断言语句,以保持统一的断言语句风格。
Client(客户端)
客户端要求能远程控制客户端,既能做简单的命令行的操作,也能做复杂的 UI
功能操作。
设计思路
通讯协议
域管客户端部署 YouQu 框架环境,并将 YouQu 框架底层能力注册到 RPC 服务,自动化用例执行端作为 RPC 客户端,在自动化用例执行过程中即可通过 RPC 协议远程调用域管客户端进行操作。
注意,这里的域管客户端是作为 RPC
的服务端,而域管的服务端是自动化脚本执行端,是作为 RPC
的客户端。
方法层
域管客户端的操作有特殊性,其在客户端的操作大多是针对有些应用的,比如打开、关闭某个应用,不像应用的操作对象一般就是应用本身。
因此,域管客户端方法层设计和应用的方法层设计也有区别,需要因地制宜。
目录结构:
client
├── __init__.py
├── udcp_widget.py # 方法层统一出口
└── widget
├── base_widget.py # 基类
├── dde_dock_widget.py # 任务栏的操作
├── dde_file_manager_widget.py # 文管的操作
├── deepin_music_widget.py # 音乐的操作
├── .... # 其他应用
└── __init__.py
- 基类处理一些通用的操作行为;
- 以应用维度划分方法类,对哪个应用的操作就封装到对应的应用类里面;
- 方法层统一出口继承所有的应用类操作,统一出口提供给上层用例调用。
客户端信息
客户端信息支持命令行入参或配置文件传入远程机器的 user
、ip
、password
信息;
用例中通过框架提供的 fixture
对象:slaves
获取数据,供用例层使用。
隐藏的宝石
(1)RPC 服务注册的问题
常规的 RPC
服务注册只能按照函数一个个显示的注册,也就是说如果要将 YouQu
所有底层能力全部释放出来,需要将 YouQu
所有提供的方法单独做封装,然后逐个注册进 RPC
服务。
这也是业内常用的方案,但是,这样功能很不好。
因为 YouQu
底层代码全是面向对象(基于类)的编程,如果全部单独封装成函数,是一个非常巨大的工作量,而且在后续底层新增修改功能后,又要对注册到 RPC
服务里面的代码进行修改;
所以我们不想要这样的 RPC
服务功能,而是希望利用好 YouQu
优秀的框架设计,能通过将 YouQu
底层统一的功能出口 src.Src
一次性注册到 RPC
服务里面,这样后续 YouQu
框架在迭代可以随意新增或修改,远程控制 RPC
服务也不用做任何修改。
解决方案
使用 zerorpc
实现 RPC
,将 YouQu
的 Src
对象注册到 zerorpc
的服务 API
zeroservices
里面,提供 RPC
服务。
从而实现零注册及维护量的 RPC
服务。
(2)代码补全的问题
域管客户端基于 RPC
实现的思路存在一个使用体验的问题,就是编写操作方法调用远程函数,在编辑器里面无法做代码补全,也不能追踪代码,使用者必须完整输入要调用的方法名称。
这对于开发者来说就是,也不是不能用,但是差点儿意思。
因此,我们希望远程控制也能实现编辑器代码补全、代码追踪。
解决方案
- 远程对象返回进行类型注解,解决通过远程对象调用远程方法时可以进行代码补全和代码追踪;
- 远程方法类里面将 YouQu 各底层类继承过来,通过属性拦截器进行特殊处理,先将方法从父类中移除,然后将方法调用传递给远程 RPC 对象,使得方法层在编写方法时,可以直接调用本地方法,但实际通过属性拦截器转换到远程对象进行调用,从而实现和本地调用相同编程体验,调用逻辑、代码维护也更加优雅简介。
总结
基于以上的实现思路,我们可以实现域管自动化测试的目标。通过使用 Playwright
实现服务端的 Web UI
自动化测试,以及通过 RPC
服务实现客户端的远程控制,我们能够有效地模拟服务端和客户端之间的交互。
对于服务端,通过 YouQu
框架提供的浏览器对象和方法层设计,我们可以实现对 Web
平台复杂 UI
功能的自动化操作。 虽然 Playwright
在自动化测试圈内知名度还不高,但我们相信未来它一定能站在领域的山顶,因此我们大胆使用它,押注未来。
对于客户端,通过 RPC
服务的部署和远程控制,我们可以实现对远程 UOS
机器上应用的自动化操作。通过应用维度的方法层设计,我们可以灵活地处理不同应用的操作,满足复杂 UI
功能测试的需求。此外,通过命令行或配置文件传入客户端信息,我们可以方便地管理远程机器的测试环境。
虽然目前存在 RPC
服务注册和代码补全的问题,但这并不影响我们基于现有思路实现域管自动化测试的目标。在后续的迭代中,我们将逐步解决这些问题,进一步提升自动化测试的体验和效果。
总之,通过以上的实现思路,我们可以信心满满地推进域管自动化测试的工作,提高测试效率,降低人力成本,为域管产品的质量和稳定性提供有力保障。