篇 10 python 自动化测试应用-python 调用安卓 adb 命令(上篇)
--lamecho 辣么丑
1.1 概要

大家好! 我是 lamecho(辣么丑),今天是《python 自动化测试应用》的第十篇,本篇文章为什么会讲 python 调用执行 adb 命令呢?因为在 web 的自动化测试框架 pyswat 完不成后,就开始编写安卓 app 的测试框架了,目前 pyapp 的框架也基本功能都完成,所以借此机会分享一下,python 怎么玩转 adb 命令。

1.2 pyapp 到底用的是 appium 还是 adb?

使用过 pyswat 框架的同学可能知道,pyswat 是底层调用的 selenium 那一套,而 pyapp 实现完全和 appium 没有一点关系。可能有同学就会问了,为什么我会这样去做?在着手设计 pyapp 框架之初,确实也纠结了,考虑了几天时间,我到底是用 appium 去实现自动化框架,还是 adb 命令去实现。最后还是确定利用 adb 命令来作为操控 app 的基础方式实现 pyapp 的自动化测试框架。接下来我先说明这样做的几点原因:
1.由于 pyapp 同样是采用录制,回放的模式(与 pyswat 框架模式一致)。那么录制的话就要考虑录制的实现,一方面是核实触发录制,也就是什么时候知道测试人员点击了 app 界面,另一方面要考虑测试人员点击的是当前 app 界面的哪个元素。解决了这两个问题基本上录制就没问题了。那么考虑到这两个因素,我们来看看 appium 能做到监控到用户的操作吗,应该没有因为我在 pyswat 里是利用了 python 写的钩子程序监控电脑的鼠标和键盘的操作,从而达到监控用户输入的目的,而在手机上是不能按照写钩子去监控到手机的。既然 appium 不行,我们转换目标看看 adb 可以吗,它有对应的命令吗?使用过 adb 命令的同学应该知道可以通过 adb shell input tap/swipe/text 命令去做点击,划屏,输入等操作,那么反过来 adb 有没有获取手机操作事件的命令呢,大家可能会想到 logcat 日志可以记录手机的操作日志,但是其实 adb 有一个 adb shell getevent 命令可以获取到当前屏幕点击事件及坐标,所以能够获取到这个重要的信息我们的录制功能基本上实现起来就没问题了。
2.第二个没有选择 appium 的原因是,大家知道 python 脚本如果搭配 appium 的话,你需要首先把 appium 的使用环境搭建起来,这一步对于新手来说或者是对于第一次使用 pyapp 框架的同学来说非常不友好(因为 pyswat 在对外发布后,发现很多同学在环境搭建上非常不熟练,产生过很多问题,导致无法正常使用 pyswat 框架),而且每次运行脚本都要启动 appium 的客户端,非常耗时,如果程序出问题还需要反复的启动关闭服务才行,无形中增加的操作成本,所以这也是抛弃 appium 作为框架底层的原因。反过来看 adb 是 android 的原生命令,你只要搭好 android sdk 就可以使用了,搭建步骤也很简单。
3.最后 adb 命令由于是 android 的原生操作命令,支持实现的功能非常多。这里举几个 pyapp 里实现的功能例子:获取,修改手机当前使用的输入法(adb shell ime list),获取当前手机界面的活动 activity(adb shell dumpsys activity activities),安装,卸载,启动 app,点击,划屏,长按,硬件输入,截屏等。
所以最后总结一下,这里只是说明 adb 命令更适合我开发 pyapp 测试框架,而不是说 appium 不好。针对只是单纯的使用 python 开发自动化脚本的同学来说,appium 更为简单些。
1.3 python 如何调用 adb 命令
Python 中执行 cmd 命令可以用到 os 和 subprocess 两个模块。区别在于 os 是阻塞式的,subprocess 是非阻塞式的,所以我们使用 subprocess 是比较适合的。接下来我先举一个查询连接设备的命令来看看 python 中怎么样的写法。用到的命令为 adb devices。
import subprocess
order='adb devices' # 获取连接设备
pi= subprocess.Popen(order,shell=True,stdout=subprocess.PIPE)
print pi.stdout.read() # 打印结果

实际打印结果,可以看到当前电脑连接了三台设备。这里需要再说明一下 adb devices 命令的结果返回是一次性的,所以我们用 read 方法读取数据是没有问题的,然而 adb 命令里还有一些是实时返回结果的,比如输出手机日志的命令 logcat,结果会不断的打印出来当前的设备操作日志信息内容,这种类型的命令我们在 python 中如果需要获取打印结果,如果还是用 read 方法的话,等待结果的返回时间会非常长,这里我们就要换一种方法读取结果,写法如下。
import subprocess
order='adb logcat'
pi= subprocess.Popen(order,shell=True,stdout=subprocess.PIPE)
for i in iter(pi.stdout.readline,'b'):
print i

这样的打印效果,如同 cmd 里操作一致,实时的打印出日志信息。这里我们就用到了 readline 方法,其实这种写法类似我们读取文件,单行读取和全部内容读取。因为目前 pyapp 的框架已经基本写完了,所以有了写这篇文章的想法,分享一些 python 在处理 adb 命令上的一些心得,就目前来看 python 在调用 adb 命令上区别主要就是这两点,最终目的是我们找到需要的功能命令获取结果数据,然后再去通过 python 处理这些返回数据,实现自动化测试的目的。大家要用好 adb 命令,还要注意一点的是每条命令的各种参数的搭配使用,比如 pyapp 的实现是支持多设备连接的,那么我们在针对某个手机进行 adb 命令操作时,就需要带上-s 加设备号,表示操作的具体设备否则命令会报错。比如我们针对一个设备去进行点击操作,命令的写法应该是这样:adb -s 49dsd4554wdsa shell input tap 600 900,其中 ‘49dsd4554wdsa’ 是设备号,‘600 900’ 点击屏幕坐标。所以可以看到增加了-s 之后就可以很方便的同时操作多台设备。
至于 adb 的相关的命令,本篇文章不会再过多的介绍,因为网上有很多相关的帖子博客都有介绍 adb 命令的,大家可以自己查阅然后通过 python 去操作实现。而后续我还要将花一篇的文章的时间去介绍一下我在编写 pyapp 框架时,遇到的一些 adb 命令需要注意的地方。可能大家在网上查阅一些 adb 命令后,尝试这自己去执行一下,发现 “诶,怎么不起作用?”,这里可能就要注意一些命令的参数搭配或者是自己所使用的设备具体的情况来定,因为目前市面上的安卓手机设备种类非常多,需要做一些适配。这里如果大家在每条的命令后加一句 –h 或是-help,可以查询一下该条命令的相关使用帮助信息。比如我们在 cmd 中输入 adb shell input –help,会返回命令相关的使用方法,我这里大概讲解一下,大家遇到其他的命令也可以自己看明白每条命令的用法了。在 Usage 这行具体告诉我们 input 后面跟的写法,[] 中括号里的内容表示可以带也可以不带,<>尖括号就是必须带上的内容。然后接下来给我们了 sources 的一些常见可用的用法,这里有看到 trackball(轨迹球),joystick(手柄),mouse(鼠标)等等,表示模拟输入的源硬件的意思,而最后是具体的命令,有 text(输入文本),keyevent(硬件操作),tap(点击)等等,这里还需要注意在具体的命令后还需要跟上具体的命令参数,怎么理解呢?比如我们是要操作 tap 命令,点击屏幕,那么我们肯定要告诉设备我们要点击的位置(坐标),所以在 tap 后把我们点击的坐标 x,y 传进去。

最后感谢大家耐心读完本篇文章,有关 adb 命令本篇只是做了一个抛砖引玉的作用,更多的还是需要大家自己多去实践不同的命令,当然在命令的选择使用上我们要有的放矢,也就是要为我们测试所用,在下一篇文章我将更多时结合具体的 adb 命令来做讲解,也会配合实际测试问题来介绍给大家如何使用 adb 命令。我是 lamecho,辣么丑,谢谢!
同时欢迎大家下载使用 pyswat,pyapp 自动化测试框架。

pyapp 框架最新更新了:1.短信验证码自动获取;2.手机 app 弱网测试;3.H5 页面元素识别等功能

原创文章,转载请注明出处。
欢迎关注我的个人微信号” firebug“,了解最新文章或提出你的问题和观点
微博:https://weibo.com/u/6017986584


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