前言
本文探讨UI自动化测试当中,操作手机的方法和不同方法所需要的环境依赖。
先从如何操作安卓手机谈起
通过屏幕坐标操作手机,无需任何环境依赖
# 1. 点击屏幕坐标(示例:点击屏幕中心点,需根据设备分辨率调整)
adb shell input tap 540 1200
# 2. 滑动屏幕(示例:从下往上滑动,模拟快速滚动)
adb shell input swipe 500 1000 500 500
# 3. 输入文本(示例:输入邮箱,需确保焦点在输入框)
adb shell input text "user@example.com"
- 优点,通过adb命令即可实现点击、滑动,输入等基本操作,无需任何其它环境依赖
- 缺点,用例难以读懂,难以维护,健壮性差(每个手机分辨率不同,同一个元素的坐标就不同,换一个手机就就要改一次坐标)
# 示例:自动化登录(假设已解锁屏幕)
adb shell input tap 300 800 # 点击用户名输入框
adb shell input text "admin"
adb shell input tap 300 1000 # 点击密码输入框
adb shell input text "123456"
adb shell input tap 500 1200 # 点击登录按钮
当然,我们也可以获取屏幕分辨率,并采用相对坐标来提高用例的健壮性。
# 获取屏幕分辨率并计算相对坐标
screen_size=$(adb shell wm size | awk -F " |x" '{print $3,$4}')
x=$((screen_width/2))
y=$((screen_height/2))
adb shell input tap $x $y
通过元素属性操作手机,你需要依赖更复杂的工具了
既然直接使用屏幕坐标来操作手机有诸多的缺点和不方便,那么更方便的方法就来了,它就是通过APP页面的元素属性来操作手机。UI Automator是google提供的测试框架。目前大部分的(其实我觉得是所有的)Android APP自动化工具,底层都是通过UI Automator的API来操作手机。
- Ui Automator访问APP页面元素的方式是通过元素的属性
UiObject2 okButton = device.findObject(
By.text("OK").clazz("android.widget.Button")
);
// Simulate a user-click on the OK button, if found.
if (okButton != null) {
okButton.click();
}
- 或者通过父子关系
UiObject2 listView = device.findObject(
By.clazz("android.widget.ListView")
.hasChild(
By.text("Apps")
)
);
- 由于UI Automator是安卓系统自带,因此原本你也无需任何外部环境依赖,只要有一部安卓手机就够了
- 但是,直接调用UI Automator的API需要写Java代码,并且以apk或者jar的形式安装到手机中运行。也就说直接用UI Automator写自动化用例,你的用例需要打包成apk安装到手机中运行。
现在可以谈谈如何操作苹果手机了
- 与安卓不同,iOS操作系统是一个封闭的生态,它并不对外提供像adb这样的工具,让你可以很方便的直接在手机上执行shell命令,比如通过类似adb shell input tap 300 800 这样的命令,来直接点击屏幕上坐标为(300,800)的点。
- 那么iOS操作系统如何满足用户的自动化测试要求呢?很简单,与安卓一样,它也提供像UI Automator这样的测试框架。iOS系统的自动化测试框架叫,XCUIAutomation。与安卓的UI Automator一样,要直接调用XCUItest的API,你必须使用Objective C或者swift进行编程,再打包成iOS应用程序安装到手机上执行测试用例。
- 来看一个官网的例子,验证点击“Add Book”按钮后,应用是否自动生成一个名为“Untitled Book”的条目,并显示在侧边栏(Sidebar)中。
@MainActor
func testClickingAddCreatesAnUntitledBook() throws {
let app = XCUIApplication()
app.launch()
let list = app.windows["Reading Journal"]
list.toolbars.children(matching: .button)["Add Book"].click()
XCTAssertEqual(list.outlines["Sidebar"].cells.containing(.button, identifier:"Untitled Book").count, 1)
}
说完原生工具再谈谈衍生工具
为什么要有衍生工具,原生工具不够用吗
安卓的UI Automator和iOS的XCUIAutomation都属于各自生态为用户提供的原生自动化测试框架,它们有一个共同的门槛,就是都需要用原生的编程语言编写测试用例,安装到手机上执行,这一条好多人是受不了的。能不能用自己擅长的编程语言(比如python, javascript)在手机之外(PC机上)编写和管理测试用例呢?必须能,于是各种各样的衍生工具就诞生了。
衍生工具的核心问题
衍生工具通常需要解决一个核心问题,非native(以python为例)代码如何调用native代码(比如OC代码,java代码)来操作手机?通常的解决方法是,开发一个代理程序。
代理程序用native代码写成,把它安装到手机上,起两个作用
- 在手机上启动一个服务器,并按照某种和客户端约定好的协议,开放出操作手机的接口。
- python代码做为客户端,按照事先约定好的协议请求这个服务器的接口,代理程序响应这个请求,然后调用native代码去操作手机。
典型的代理程序
FaceBook开源的UI自动化测试工具APPIUM是目前最著名的衍生工具,它开源了所有的重要组件,其中
webdriveragent(iOS)和uiautomator2 (Android)就是代理程序。如果有兴趣进一步学习和开发自己的代理程序,可以学习下这两个开源项目。
不用手指操作手机的N中方法