你是否曾经想过有一天你手里的手机在你不动它的情况下,自己点来点去,打开各种 app,操作来操作去。其实这一天已经到来,而且你还可以按照自己的想法,让手机自动化的去操作。
要想让手机实现自动化,你可能需要学习一点 Python,这是一门简单易懂的计算机编程语言,非常容易学习和编写。如果你有其他语言的基础,一天学习下来,差不多可以拿 Python 写个小程序了。这门语言发展了十多年,数不清的 Python 使用者为 Python 贡献了无数多的库,有了合适的库,就仿佛战场上的你有了一个趁手的兵器,可以瞬间增加战斗力。
今天这篇文件介绍的也是一个库,名字是 uiautomator2, 在https://pypi.python.org/pypi/uiautomator2 上可以看到。
适用范围
Android 手机 4.3+(sdk 18)
从 Python 官网https://python.org下载安装完之后(推荐 Python3),使用Win + R
快捷键,输入cmd
,然后回车,可以看到一个命令行窗口。(国际惯例,我把名字模糊了)
命令行窗口输入pip install -U --pre uiautomator2
经过短暂的等待,就安装好了。部分情况可以因为中国互联网防火墙的原因,安装不了,这是可以试试用国内的 pypi 镜像
pip install -U --pre uiautomator2 -i https://pypi.doubanio.com/simple
如果需要更新这个库,重新运行一下这个命令就可以。
uiautomator2 库通过 http 协议与手机上的服务通信,完成我们想要的自动化。手机上的服务是我们自己实现的,原本是没有的,所以在测试之前,我们需要做一下预处理。
预处理需要向手机上安装 5 个组件,分别是
一个个的手动安装未免有点麻烦,所以我们提供了更快捷的方法。
首先将设备插入到手机上,如果提示信任开发者选项
就点击确认。
# 先确认下是否可以看到可用设备
$ adb devices
List of devices attached
3578298f device
# 开始将这5个零件安装到手机
$ python -m uiautomator2 init
2018-03-22 10:14:09,218 - __main__.py:268 - INFO - Detect pluged devices: ['3578298f']
2018-03-22 10:14:09,218 - __main__.py:284 - INFO - Device(3578298f) initialing ...
2018-03-22 10:14:09,722 - __main__.py:113 - INFO - install minicap
2018-03-22 10:14:09,943 - __main__.py:120 - INFO - install minitouch
2018-03-22 10:14:10,361 - __main__.py:137 - INFO - apk(1.0.12) already installed, skip
2018-03-22 10:14:10,460 - __main__.py:175 - INFO - atx-agent(0.2.1) already installed, skip
2018-03-22 10:14:10,700 - __main__.py:212 - INFO - launch atx-agent daemon
2018-03-22 10:14:13,711 - __main__.py:228 - INFO - atx-agent output: server started, listening on 10.242.62.224:7912
2018-03-22 10:14:14,459 - __main__.py:232 - INFO - success
安装过程中会联网下载组件,安装到最好当看到提示success
的时候问题就不大了。
如果安装失败,可以加 QQ 群 497460177, 或者查看 FAQ 贴 https://testerhome.com/topics/12025 通常来说都不是什么大问题。
接下来看一段 Python 脚本
# coding: utf-8
import uiautomator2 as u2
u = u2.connect_usb()
u.make_toast("Hello world", 3)
运行这段代码,手机上会发现有一台Hello world
消息显示 3s 后消息。部分手机需要设置下运行悬浮窗的功能,比如小米。
参考该链接 百度经验 小米手机打开应用悬浮窗,允许 uiautomator 应用显示悬浮窗
如果这一步成功了,恭喜你,你即将跨入自动化测试的大门。
手机先下载一个网易云音乐,下载链接http://music.163.com/#/download。手机上有的就不用再安装了。
# coding: utf-8
import uiautomator2 as u2
u = u2.connect_usb()
sess = u.session("com.netease.cloudmusic") # 启动网易云音乐
sess(text="私人FM").click()
session
u.session
函数会先重启应用,返回 session object,如果应用闪退,通过 session object 进行的所有操作都会抛出异常。
如果不希望 session 函数杀掉应用,可以这样 sess = u.session("com.netease.cloudmusic", attach=True)
sess(text="私人 FM").click()
查找界面上组件的 text 为私人FM
的组件,然后执行点击操作
通过刚才的两个 Hello world,相信你已经稍微认识了 uiautomator2,下面我们给代码加入更多的功能。
# coding: utf-8
import unittest
import uiautomator2 as u2
import time
import uiautomator2.ext.htmlreport as htmlreport
class TestCloudMusic(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.u = u2.connect_usb()
cls.u.healthcheck() # 解锁屏幕并启动uiautomator服务
hrp = htmlreport.HTMLReport(cls.u, 'report')
hrp.patch_click()
# cls.u.disable_popups(True) # 允许自动处理弹出框
cls.u.make_toast("测试开始", 3)
@classmethod
def tearDownClass(cls):
cls.u.make_toast("测试结束", 3)
cls.u.app_stop_all()
cls.u.service(
"uiautomator").stop() # 停止uiautomator守护程序,允许其他测试框架如 appium 运行
def setUp(self):
self.d = self.u.session("com.netease.cloudmusic") # restart app
time.sleep(5) # 等待首页广告结束
def tearDown(self):
pass
def testPrivateFM(self): # 私人FM
self.d(text="私人FM").click()
def testRecommendEveryday(self): # 每日推荐
self.d(text="每日推荐").click()
if __name__ == '__main__':
unittest.main()
这个例子更加完善,新增了 unittest 集成,htmlreport 插件的集成以及 uiautomator service 相关的控制代码。
unittest
unittest 是 python 自带的单元测试库。新建一个类继承自 unittest.TestCase。类里面我们写了两个以test
开头的函数,我们称这两个函数为测试单元。
当我们运行unittest.main()
的时候,这些测试单元会被依次调用。其中的setUp
函数在每个测试单元调用之前被调用,而tearDown
则在之后被调用。
setUpClass
函数在所有测试单元调用完之前调用,相应的tearDownClass
在所有测试单元调用完之后调用。
healthcheck 和 d.service("uiautomator").stop()
healthcheck
函数相当于飞机起飞前的自检。因为我们的 uiautomator 库依赖于手机上运行的 UiAutomator 服务,所以运行之前最好能够检查一下。
最后的d.service("uiautomator").stop()
是因为,安卓上的 UiAutomator 是独享的,一旦一个服务使用了它,其他人就不让碰了。所以 appium
, macaca
, uiautomatorviewer.bat
只要你用了 UiAutomator 服务,都是冲突的。只有再用完之后,停止掉 uiautomator service,才能让其他服务使用。
如果你只用我们这一个库,也是可以不用 stop 掉这个 service 的。
htmlreport
htmlreport 是为了方便记录测试结果写的一个扩展。想知道实现的人可以看看源码https://github.com/openatx/uiautomator2/tree/master/uiautomator2/ext/htmlreport
测试运行完之后,会在代码运行目录下生成一个 reoprt 目录。
因为浏览器限制的原因,直接双击打开的 html 不能加载本地的 json,所以必须要一个简单的文件服务器。双击start.bat
就算是启动了一个简易的 python 文件服务器。
浏览器可以看到一个简单的包含截图的测试记录
app_stop_all
这个函数相当于手机回到桌面后,关闭后台进程。
为了方便的写代码,我们还要用到另外一个项目weditor, 可以很方便的查看当前界面的元素信息,写起脚本来飞快。
项目地址 https://github.com/openatx/uiautomator2