韩师傅就是我

测试开发工程师

不用手指操作手机的N中方法

前言

本文探讨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中方法

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Scroll to top