简介

前些日志在社区看了【有赞团队的一篇记一次基于 Robotium 改造的测试实践】
https://testerhome.com/articles/18752.

文章中提到了自动化测试可以拖离 PC 运行,点击 apk 中的运行按钮就能开启自动化测试,这个思路给了我很大的启发.

本文就尝试把 Android Monkey 测试脱机运行,截止到写这片文章.基本功能已经实现,还查一些适配问题和优化.

自动化框架对比

现在主流移动端自动化框架,基本上都是在 pc 上运行来操作移动端设备.

Appium

这种 cs 架构的自动化框架,需要在 pc 上开启一个服务,然后手机上安装各种的可以通信的 app,比如 bootstrap、wda 等.在启动测试脚本后、bootstrap 接受指令,最后调度 UiAutomator 或者 UiAutomator2 底层引擎操作移动设备.

Robotium

这个项目现在已经不怎么更新了,依托 Android 测试环境的核心是 Instrumentation 框架,有依赖源码使用和不依赖源码使用的两种方案.在【有赞】的文章中提到了 Robotium 框架,但是看了一些 Robotium 的环境搭建贴还是停留在 ecliese 上并且都是 3 年以前的,果断放弃了.

atx

底层基于 Google uiautomator,安装 atx-agent 后会在手机上开启一个 http 端口.也就是说服务端从 pc 上挪到了手机本身上了,这样就可以脱离 pc 达到效果.

UiAutomator2

UiAutomator2 是 Android 提供的一个自动化测试框架,基于 Instrumentation 框架.提供了丰富的 api 方法来操作设备,Appium 中也提供了 UiAutomator2 底层引擎.

脱机运行方案

综合了上面几个自动化测试方案,决定使用【UiAutomator2】框架.不需要开启任何端口、和 Android 项目天然结合.

使用

先简单介绍下 UiAutomator2 如何使用和一些常用 api

创建一个 Android UiAutomator2 项目

创建一个带页面的项目,为了后期在页面中运行自动化测试做准备.

image

自动创建好项目后,会有个 androidTest 文件夹和 ExampleInstrumentedTest.java 文件.

image

在 app 路径下的 build.gradle 文件添加依赖.

image

通过 Intent 启动 app、创建 UiDevice 实例并使用 api 方法,如点击元素和滑动等.

image

点击运行方法按钮,会使用 gradle 打一个 androidTest.apk 安装到手机上.

image

启动测试命令如下:

adb shell am instrument -w -r -e debug false -e class 

'android.example.xinxi.monkey.ExampleInstrumentedTest#testDemo'

com.bilibili.test/android.support.test.runner.AndroidJUnitRunner

常用 api

click

根据坐标点击屏幕

swipe

滑动屏幕

drag

拖拽屏幕

findObject

查询元素

dumpWindowHierarchy

获取页面 xml 元素

executeShellCommand

执行 shell 命令

pressBack

模拟返回

参数传递

在上面提到 instrument 命令行启动,是可以传递参数给测试类的.主要用途是传递测试时间和测试包名.

用法如下:

adb shell am instrument -w -r -e runtime 10 debug false -e class 
# 运行10分钟测试脚本

Bundle bundle = InstrumentationRegistry.getArguments();
TIMING  = Integer.parseInt(bundle.getString("runtime"));
# 在代码中使用getArguments接收参数并获取字段值

Monkey

Monkey 这部分设计,是把随机点击、滑动、返回、滚动等常用 api 结合起来,通过分配事件概率控制.

image

image

apk 内执行

上面已经完成了 Monkey 开发并且可以通过命令行测试 app,但是还是需要依托 pc.

所以需要一个 apk 执行 instrument 命令,这样就可以脱离了 pc.

创建 MainActivity 增加【运行】和【停止】按钮,增加运行时间输入框.会在点击【运行】按钮的同时把【时间】参数传递给【测试类】.

image

需要主要注意的是,执行 instrument 命令是个耗时操作,所以创建了一个子线程来执行.

image

展示效果

run.gif

app 获取系统权限

目前仅对模拟器和 root 过的手机适配过,原因在于在 app 内部执行 shell 命令需要系统权限.

解决方案是给 app 添加系统权限并且系统权限签名,在 AndroidManifest.xml 增加"android:sharedUserId="android.uid.system",然后使用 platform.pk8 和 platform.x509.pem 文件签名.

这个解决方案参考了一些帖子,尚未成功过,后续有时间了再调研.

崩溃获取

在 Android 中可以自定义 CrashHandler 类来捕获崩溃,需要一个当前 app 的上下文环境,现在还获取不到被测 app 的崩溃,这个问题也后续调用如何捕获运行时崩溃.

CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(getApplicationContext());

结语

畅想以后的移动端自动化测试,只要把该功能集成到被测 app 的 debug 环境中,任何开发同学和测试同学都可以无成本的使用,最终达到【自动化触手可及】的效果.

项目地址: https://github.com/xinxi1990/MonKeyTest

参考

UIAutomator2.0 详解(入门篇)

https://blog.csdn.net/daihuimaozideren/article/details/78331673

安卓 apk 重签名工具

https://github.com/pengwei1024/apkReSign/

Android Studio 在只有 apk 情况下的的 robotium 自动化框架应用

https://blog.csdn.net/wokankanhao88/article/details/81335650

https://developer.android.com/training/testing/ui-testing/uiautomator-testing.html

如何启动 instrumentation ?(android )

https://blog.csdn.net/duan5858/article/details/54670397

uiautomator2.0+ 脱离 PC 运行(apk 启动 uiautomator2.0+)的实现方案

http://www.voidcn.com/article/p-tkfwaruq-beo.html

keytool-importkeypair

https://github.com/getfatday/keytool-importkeypair

让 Android Studio 支持系统签名 (证书)

https://zhuanlan.zhihu.com/p/48131789

实现 uiautomator2.0 脱离 PC 运行

博客地址:https://blog.csdn.net/pgz100
https://github.com/pgz100/myuiautomator

Andorid 任意界面悬浮窗,实现悬浮窗如此简单

https://www.jianshu.com/p/18cbc862ba7b
https://github.com/yhaolpz/FloatWindow

Android Studio 自动生成带系统签名的 apk

https://blog.csdn.net/cxq234843654/article/details/51557025

Uiautomator 2 调试参数传递

https://blog.csdn.net/sinat_29052561/article/details/

UIAutomator2.0 简介

https://testerhome.com/topics/3588


↙↙↙阅读原文可查看相关链接,并与作者交流