monkeyrunner自动化工具详解
monkeyrunner简介
①monkeyrunner工具使用Jython,这是一种使用Java编程语言的Python实现。Jython允许monkeyrunner API与Android框架轻松交互。使用Jython可以使用Python语法来访问API的常量,类和方法。monkeyrunner提供了多个API,通过monkeyrunner API 可以写一个Python的程序来模拟操作控制Android设备或者Android虚拟机的app,测试其稳定性并通过截屏可以方便地记录出现的问题。
②monkeyrunner官网对monkeyrunner工具的解释介绍:
monkeyrunner工具提供了一个API,用于编写从Android代码外部控制Android设备或模拟器的程序。使用monkeyrunner,您可以编写一个Python程序,安装Android应用程序或测试包,运行它,向其发送击键,截取其用户界面,并在工作站上存储屏幕截图、monkeyrunner工具主要用于测试功能/框架级别的应用程序和设备以及运行单元测试套件,但您可以将其用于其他目的。
③monkeyrunner工具即Android SDK中自带的工具之一,此工具提供API可控制android设备或模拟器。
④monkeyruuner测试工具的官方网站:monkeyrunner官网
⑤monkeyrunner在Android SDK中的路径:Andriod_SDK\tools
MonkeyRunner测试工具的独特功能
①多设备控制:monkeyrunner API可以跨多个安卓设备或安卓模拟器应用一个或多个测试套件。可以物理连接所有安卓设备或启动所有安卓模拟器(或两者方式同时使用),以编程方式依次连接到每个Android设备,然后运行一个或多个测试。还可以以编程方式启动模拟器配置,运行一个或多个测试,然后关闭模拟器。(monkeyrunner API可以跨多个设备,一次启动全部模拟器来实施测试套件)
②功能测试:monkeyrunner可以对Android应用程序进行自动化的从头到尾的测试。可以通过击键或触摸事件提供输入值,并将结果视为屏幕截图。(为Android应用自动执行一次功能测试,然后观察输出结果的截屏)
③回归测试:monkeyrunner可以通过运行应用程序并将其输出屏幕截图与一组已知已存在正确的屏幕截图进行比较来测试应用程序的稳定性。
④可扩展的自动化:由于monkeyrunner是一个API工具包(在python中可以理解为可调用的一个模块,模块中是工具类),可以开发一个基于Python的模块和程序的整个系统来控制Android设备。除了使用monkeyrunner API本身,您还可以使用标准的Python os和 subprocess 模块来调用Android工具,例如 Android Debug Bridge。
⑤还可以自己封装操作Android设备/Android模拟器的工具类添加到monkeyrunner API中,即使用插件扩展monkeyrunner
Monkeyrunner与Monkey的区别
1、monkeyrunner和money没有什么直接的关系;monkey是在Android设备/Android模拟器直接运行adb shell命令生成随机事件来进行测试的。相比较而言,monkeyrunner则是通过API发送特定的命令和事件来控制设备。(类比selenium工具)
2、为了支持黑盒自动化测试的场景,Android SDK提供了monkey和monkeyrunner两个测试工具,这两个测试工具除了名字类似外,还都可以向待测应用发送按键等消息,往往容易产生混淆,以下是他俩的不同之处。
Monkey测试工具:
①monkey运行在设备或者模拟器中,可以脱离PC运行,其运行时如下图所示:
Monkeyrunner测试工具:
①Monkeyrunner测试工具是在工作站上通过API定义的特定命令和事件控制设备或模拟器。
②monkeyrunner运行在PC上,需要通过客户端/服务端的的模式向Android设备或者Android模拟器上的Android应用发送指令来执行测试,其运行时如下图所示:
3、普遍的做法是将monkey作为一个向待测Android应用发送随机按键消息的测试工具,验证待测Android应用在这些随机性的输入事件中面前是否会有闪退或者崩溃。
而monkeyrunner则接受一个明确的测试脚本(使用python语言编写的)来实现对Android应用的控制。
4、虽然monkey也可以根据一个指定的命令脚本发送按键消息,但其不支持条件判断,也不支持读取界面的信息来执行验证操作。(monkey测试工具只是用于测试Android应用的稳定性,通过查看money命令的运行日志校验随机事件运行期间是否Android应用发生异常)
而monkeyrunner的测试脚本中有明确的条件判断等语句,可用来做功能测试。
总结:
①实际操作中,monkey由于缺少必要的条件判断等命令,难以在功能测试上有所作为,只能作为生成一些随机事件的工具,测试Android应用程序的健壮程度,待测Android应用崩溃后可以根据monkey产生的日志,再用monkey命令创建一个重现步骤,供开发调试。monkey服务器模式更适合用于黑盒测试,不建议用于自动化测试。
②Monkeyrunner虽然有Python和Java类库的强大支持,但其自身提供的API有限,还得需要插件扩展其功能。
monkeyrunner API
MonkeyRunner工具(monkeyrunner API)( com.android.monkeyrunner包中)主要有三个类: MonkeyRunner 、 MonkeyDevice 、 MonkeyImage
① MonkeyRunner 类:提供连接Andriod真机和Andriod模拟器方法 waitForConnection(float timeout,string deviceid) ,还有显示提示显示信息的 alert() 方法。
② MonkeyDevice 类:表示设备或模拟器。提供了安装和卸载程序包、开启Activity、发送按键和点击事件、运行测试包等方法。
拖拉控件:drag(tuple start,tuple end,float duration,integer steps) # duration手势持续时间
按键: press(string keycode,dictionary type) # keycode:KEYCODE_HOME,..;type:DOWN ,UP,DOWN_AND_UP...
安装应用: installPackage(pc端存放apk的路径)
启动应用: starActivity(package+'/'+activity) # '/'用来连接包名和界面名(一个参数)
点击: touch(integer x,integer y, integer type) # type:DOWN,UP,DOWN_AND_UP...
输入: type(string message)
截屏: takeSnapshot()
③ MonkeyImage 类:此类提供捕获屏幕,将位图图像转换为各种格式,比较两个MonkeyImage对象以及将图像写入文件的方法。
图像对比 :sameAs(MonkeyImage other,float percent) # 对比的相似度,结果boolean类型
图像保存 :writetoFile(string path,string format)
在Python程序中,可以将每个类作为Python模块进行访问。monkeyrunner测试工具不会自动导入这些模块。要导入模块,请使用Python from 语句:
from com.android.monkeyrunner import <module>
运行monkeyrunner
可以从文件中直接运行monkeyrunner程序;也可以在交互式会话(即cmd终端)中输入monkeyrunner语句。
①如果提供文件名作为参数,则该monkeyrunner命令将文件的内容作为Python程序运行; (使用Python编写测试代码文件,在CMD中执行 monkeyrunner 文件名.py运行)
monkeyrunner -plugin <plugin_jar> <program_filename> <program_options>
参数详解:
参数 | 描述 |
---|---|
-plugin <plugin_jar> |
(可选)指定.jar 包含monkeyrunner插件的文件。要了解有关monkeyrunner插件的更多信息,请参阅 使用插件扩展monkeyrunner。要指定多个文件,请多次包含该参数。 |
<program_filename> |
如果提供此参数,则该monkeyrunner 命令将该文件的内容作为Python程序运行。如果未提供参数,则该命令将启动交互式会话。 |
<program_options> |
(可选)<program_file>中程序的标志和参数。 |
②如果不提供文件名作为monkeyrunner命令的参数,则会启动一个交互式会话。(在CMD命令窗口直接运行monkeyrunner)如下图:
【注意】在运行monkeyrunner命令之前必须先运行相应的Android模拟器或连接Android真机,否则monkeyrunner工具无法连接到设备。
monnkeyrunner测试工具使用实例
实例1:卸载旧的Android APP,安装新的Android APP
方式一:
①连接Android模拟器成功。
②打开CMD窗口,运行monkeyrunner命令。
③进入monkeyrunner的shell命令交互模式后,逐条输入以下命令
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage device = MonkeyRunner.waitForConnection() device.removePackage('com.baidu.searchbox') device.installPackage(r'E:\Android_apk\baidusearch1006979t.apk')
(1)输入命令前的夜神模拟器:
(2)输入第三行命令后的夜神模拟器:
(3)输入第四行命令后的夜神模拟器:
(4)CMD终端命令行截图:
方式二:
①编写Python测试代码:
# coding=utf-8 # 引入本程序所用到的模块 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage # 连接手机设备 device = MonkeyRunner.waitForConnection() # 截图 result = device.takeSnapshot() # 将截图保存到文件 result.writeToFile('E:\\manage\\Test1_001.png', 'png') # 卸载APP device.removePackage('com.baidu.searchbox') print('Uninstall Success!') # 暂停5秒 MonkeyRunner.sleep(5) # 截图 result = device.takeSnapshot() result.writeToFile('E:\\manage\\Test1_002.png', 'png') # 安装新的APP device.installPackage(r'E:\Android_apk\baidusearch1006979t.apk') print('Install Success!') # 暂停5秒 MonkeyRunner.sleep(5) # 截图 result = device.takeSnapshot() # 将截图保存到文件 result.writeToFile('E:\\manage\\Test1_003.png', 'png')
【注意】monkeyrunner命令运行python程序时需要去除中文注释;或者在模块开头添加#coding=utf-8。
②将上述python脚本保存为test_1.py,保存路径为E:\python_script\test_1.py。
③CMD终端中执行test_1.py脚本:
monkeyrunner E:\python_script\test_1.py
运行截图:
③检查Android模拟器里的百度app是否更新
④检查保存Android模拟器截屏的文件夹E:\\manage。检查是否和程序中的截屏信息相同。
monkeyrunner测试工具常用的知识点
①引入程序所用的模块
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage
或者,使用别名的方式引入程序所用的模块
from com.android.monkeyrunner import MonkeyRunner as mr from com.android.monkeyrunner import MonkeyDevice as md from com.android.monkeyrunner import MonkeyImage as mi #如果给导入的模块起了别名,就必须使用别名,否则会出现错误。 #比如连接设备或模拟器,起了以上别名后,命令应该如下: device=mr.waitForConnection()
②#连接到Android设备或Android模拟器
#参数1:超时时间,单位秒,浮点数。默认是无限期地等待。 #参数2:串deviceid,指定的设备名称。默认为当前设备(手机优先,比如手机通过USB线连接到PC、其次为模拟器)。
#默认连接: device = MonkeyRunner.waitForConnection() #参数连接: device = MonkeyRunner.waitForConnection(1.0,'4df74b8XXXXXXX')
③向Android设备或Android模拟器安装APK
#以下两种方式都是对的 #参数可以为绝对路径,也可为相对路径
#安装成功返回true
device.installPackage('E:/JAVA/monkeyrunner/Test1/ThinkDrive_new.apk') device.installPackage('E:\\JAVA\\monkeyrunner\\Test1\\ThinkDrive_new.apk')
④卸载Android设备或Android模拟器中的APK
#参数为APK包名 device.removePackage('cn.richinfo.thinkdrive')
⑤启动任意的Activity(Android应用的启动)
#device.startActivity(component="包名/启动Activity") #以下两种都可以 device.startActivity(component="cn.richinfo.thinkdrive/cn.richinfo.thinkdrive.ui.activities.NavigateActivity") device.startActivity(component="cn.richinfo.thinkdrive/.ui.activities.NavigateActivity")
⑥手机截图+截图保存至本机
#获取设备的屏蔽缓冲区,产生了整个显示器的屏蔽捕获。(截图) result=device.takeSnapshot() #返回一个MonkeyImage对象(点阵图包装),可以用以下命令将图保存到文件 result.writeToFile('E:\\JAVA\\monkeyrunner\\Test1\\Test1_001.png','png')
⑦等待(类比python程序中的sleep)
#暂停目前正在运行的程序指定的秒数 #MonkeyRunner.sleep(秒数,浮点数) MonkeyRunner.sleep(5)
⑧字符串发送到键盘
#device.type('字符串') device.type('hongge')
⑨唤醒Android设备的屏幕
#锁屏后,屏幕关闭,可以用下命令唤醒 device.wake()
⑩重启手机
device.reboot()
①①模拟Android滑动
#device.drag(X,Y,D,S) #X 开始坐标 #Y 结束坐标 #D 拖动持续时间(以秒为单位),默认1.0秒 #S 插值点时要采取的步骤。默认值是10 device.drag((100,1053),(520,1053),0.1,10)
①②在指定位置发送触摸事件+发送指定类型指定键码的事件
#device.touch(x,y,触摸事件类型---点击屏幕) #x,y的单位为像素 device.touch(520,520, 'DOWN_AND_UPshishi)
①③按键操作
#device.press(参数1:键码, 参数2:触摸事件类型) #参数1:见android.view.KeyEvent #参数2,如有TouchPressType()返回的类型-触摸事件类型,有三种。 #触摸事件类型: #1、DOWN 发送一个DOWN事件。指定DOWN事件类型发送到设备,对应的按一个键或触摸屏幕上。 #2、UP 发送一个UP事件。指定UP事件类型发送到设备,对应释放一个键或从屏幕上抬起。 #3、DOWN_AND_UP 发送一个DOWN事件,然后一个UP事件。对应于输入键或点击屏幕。
#以上三种事件做为press()参数或touch()参数 #按下HOME键 device.press('KEYCODE_HOME', MonkeyDevice.DOWN_AND_UP) #按下BACK键 device.press('KEYCODE_BACK', MonkeyDevice.DOWN_AND_UP) #按下下导航键 device.press('KEYCODE_DPAD_DOWN', MonkeyDevice.DOWN_AND_UP) #按下上导航键 device.press('KEYCODE_DPAD_UP', MonkeyDevice.DOWN_AND_UP) #按下OK键 device.press('KEYCODE_DPAD_CENTER', MonkeyDevice.DOWN_AND_UP)
Android设备或虚拟机中相应的按键对应的名称如下:
home键: KEYCODE_HOME
back键: KEYCODE_BACK
send键: KEYCODE_CALL
end键: KEYCODE_ENDCALL
上导航键: KEYCODE_DPAD_UP
下导航键: KEYCODE_DPAD_DOWN
左导航: KEYCODE_DPAD_LEFT
右导航键: KEYCODE_DPAD_RIGHT
ok键: KEYCODE_DPAD_CENTER
上音量键: KEYCODE_VOLUME_UP
下音量键: KEYCODE_VOLUME_DOWN
power键: KEYCODE_POWER
camera键: KEYCODE_CAMERA
menu键: KEYCODE_MENU