lena萌宝宝

导航

机器人自动化测试方案(monkeyrunner)

 

 

压力测试工具-monkey

1.1 Monkey简介

1.2 Monkey基本使用

1.3 Monkey工具使用实例

自动化测试工具-monkeyrunner

1.4 Monkeyrunner简介

1.5 Monkeyrunner工具特性

1.6 Monkeyrunner常用API

1.7 测试环境准备

1.8 Monkeyrunner脚本编写

1.9 测试结果分析

  

一、 压力测试工具-monkey

1.1 Monkey简介

Monkey测试是Android平台自动化测试的一种手段,通过Monkey程序模拟用户触摸屏幕、滑动Trackball、按键等操作来对设备上的程序进行压力测试,检测程序多久的时间会发生异常 传统意义上,Monkey测试主要针对的是应用的健壮性与稳定性,它通过大量的随机的用户事件来检测应用是否会异常。

 

1.2 Monkey基本使用

1)常规命令

Adb shell monkey -v

-v:指定打印信息的详细级别,一个 -v增加一个级别 , 默认级别为 0

--help:打印帮助信息

2)事件类命令

-f后接测试脚本名,表示用monkey运行指定的monkey脚本

-s:指定产生随机事件种子值,相同的种子值产生相同的事件序列。如: -s 200
--throttle:每个事件结束后的间隔时间——降低系统的压力(如不指定,系统会尽快的发送事件序列)。如:--throttle 100
--pct-touch:指定触摸事件的百分比,如:--pct-touch 5% ,

相关的还有以下option:
--pct-motion <percent> (滑动事件)、 --pct-trackball <percent> (轨迹球事件) 、 --pct-nav <percent> (导航事件 up/down/left/right)、 --pct-majornav <percent> (主要导航事件 back key 、 menu key)、 --pct-syskeys <percent> (系统按键事件 Home 、Back 、startCall 、 endCall 、 volumeControl)、 --pct-appswitch <percent> (activity之间的切换)、 --pct-anyevent <percent>(任意事件)

3)约束类命令

-p:指定有效的package(如不指定,则对系统中所有package有效),一个-p 对应一个有效package, 如:-p com.ckt -p com.ckt.asura;
-c:activity必须至少包含一个指定的category,才能被启动,否则启动不了;

 

4)调试类命令

--dbg-no-events:初始化启动的activity,但是不产生任何事件。
--hprof:指定该项后在事件序列发送前后会立即生成分析报告  —— 一般建议指定该项。
--ignore-crashes:忽略崩溃
--ignore-timeouts:忽略超时
--ignore-security-exceptions:忽略安全异常
--kill-process-after-error:发生错误后直接杀掉进程
--monitor-native-crashes:跟踪本地方法的崩溃问题
--wait-dbg:知道连接了调试器才执行monkey测试。

 

1.3 Monkey工具使用实例

 

1.需求:对机器人进行设置应用进行压力测试

 

2.测试准备和执行

Monkey测试前,必须进行以下准备

Ø 1)设置屏幕超时设置为30分钟,防止进入锁屏状态。

Ø 2)开启ADB模式,连接到PC

Ø 3)开启系统log

Ø 4)在PC上执行 运行—>CMD,在弹出的命令窗口中,输入adb devices,检查设备是否连接 ,在弹出的命令窗口中,输入adb shell,进入Linux Shell ,输入Monkey命令。

如下:

monkey -p com.avatar.settings --ignore-crashes --ignore-timeouts --ignore-native-crashes --pct-touch 30 -s 1 -v -v --throttle 200 100000 2>/sdcard/error.txt 1>/sdcard/info.txt 

参数意义:

-p com.avatar.settings

只仅针对特定包名进行测试

--ignore-crashes

忽略应用程序崩溃(Force & Close错误),继续发送执行事件,直到事件数执行完成

--ignore-timeouts

忽略应用程序发生ANR(Application No Responding)错误时,直到事件数执行完成

--ignore-native-crashes

忽略本地应用程序发生奔溃,直到事件数执行完成

--pct-touch 30

调整触摸事件为30%。即整个事件过程中触摸事件占30%

-s 1

伪随机数生成器seed值。Seed值为1。相同的seed值再次执行monkey,将产生相同的事件序列

-v -v

日志级别为Leve1 1。将提供较为详细的日志,包括每个发送到Activity的事件信息

--throttle 200

事件之间延时200毫秒。可以控制monkey的执行速度,如果不指定该选项,monkey事件间将不会延时

100000

执行事件数为10万次

2>/sdcard/error.txt

Leve1 2日志保存到sdcard 上的error.txt中,主要记录了MONKEY测试时产生的一些ANR、强制关闭等异常

1>/sdcard/info.txt

Leve1 1日志保存到sdcard 上的info.txt中,主要记录了MONKEY测试时发送的各种事件,如触摸事件的位置等等

 

 

3.测试结果分析

1)初步定位方法:

Monkey测试出现错误后,一般的差错步骤为以下几步:

1、 找到是monkey里面的哪个地方出错

2、 查看Monkey里面出错前的一些事件动作,并手动执行该动作

3、 若以上步骤还不能找出,可以使用之前执行的monkey命令再执行一遍,注意seed值要一样

 

2)常见错误分析

1)Null指针异常

空指针异常主要是有NullPointerException异常提示,如果Monkey命令被中断,说明有异常信息并且有对应的打印信息,可以看到如下信息,说明几个问题:

A、android.process.acore该进程出现异常

B、异常信息主要是由于NullPointerException引起的,也就是出现了空指针,导致了acore进程进入debug

***************************************

// CRASH: android.process.acore (pid 1339)

// Short Msg: java.lang.NullPointerException

// Long Msg: java.lang.NullPointerException

// Build Label: android:FIH/msm7627_surf/msm7627_surf/F0X:1.6/DONUT/0001_0_020:e

ng/release-keys

// Build Changelist: -1

// Build Time: 1271397239

// ID:

// Tag: AndroidRuntime

// java.lang.NullPointerException:

//   at

 

2)debug异常

debug异常主要是由于应用程序本身的错误导致的异常。一般情况下,出现的该问题,很可能在手动测试时也可以测试到。

A、com.android.browser该进程进入debug

B、出现的是IllegalStateException异常,该异常一般多是传递的参数非法或被多次调用时出现的异常

************************************************************************

// CRASH: com.android.browser (pid 5683)

// Short Msg: Connection is not open

// Long Msg: java.lang.IllegalStateException: Connection is not open

// Build Label: android:FIH/msm7627_surf/msm7627_surf/F0X:1.6/DONUT/0001_0_020:eng/release-keys

// Build Changelist: -1

// Build Time: 1271397239

// ID:

// Tag: AndroidRuntime

// java.lang.IllegalStateException: Connection is not open

//   at android.net.http.AndroidHttpClientConnection.assertOpen(AndroidHttpClien

tConnection.java:153)

//   at android.net.http.AndroidHttpClientConnection.setSocketTimeout(AndroidHtt

pClientConnection.java:195)

//   at android.net.http.Connection.openHttpConnection(Connection.java:364)

//   at android.net.http.Connection.processRequests(Connection.java:225)

//   at android.net.http.ConnectionThread.run(ConnectionThread.java:116)

** System appears to have crashed at event 34155 of 5000000 using seed 0**

 

3)操作无响应异常

  主要表现在Monkey运行过程中,出现某功能无响应,提示是否“强制关闭“或“等待“,出现ANR,一般是主线程的响应超过5秒,或者BroadcastReceiver没有在10秒内作出响应。这个就是一个比较严重的缺陷。如下可以说明com.avatar.dialog该进程出现的无响应ANR说明有bug。

***************************************

// NOT RESPONDING: com.avatar.dialog (pid 21982)

ANR in com.avatar.dialog

PID: 21982

Reason: Executing service com.avatar.dialog/com.avatar.speech.AvatarSpeechService

 

4)其他异常

A、Restart System异常(系统重新启动),即log信息的最后几行会看到Restart System的打印信息,说明设备被自动的重启或断掉,有几个方面的原因

1、运行过程中,存在异常被自动重启

2、在运行过程中,进入设置中的恢复出场设置,导致重启

 

B、RuntimeException等异常,该问题多出现在操作无响应之后,或者是某应用的服务无法启动或连接时,比如:

***************************************

// CRASH: android.process.media (pid 18925)

// Short Msg: android.content.ActivityNotFoundException

// Long Msg: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.provider.action.MANAGE_ROOT dat=content://com.android.providers.downloads.documents/root/downloads }

// Build Label: rockchip/rk3288/rk3288:4.4.4/KTU84Q/eng.avatarmind.20160606.093049:eng/test-keys

// Build Changelist: eng.avatarmind.20160606.093049

// Build Time: 1465176899000

// java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.providers.downloads.ui/com.android.providers.downloads.ui.DownloadList}: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.provider.action.MANAGE_ROOT dat=content://com.android.providers.downloads.documents/root/downloads }

// at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2249)

// at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2298)

 

C、StaleDataException、readException等异常, 该信息说明android的数据库操作出现异常

 

D、IllegalArgumentException等异常,说明向函数传递了一个不正确或不合法的参数

 

E、低内存异常,主要表现在出现OutOfMemoryError异常或者提示Out of memory,其后果同样表现为抛出OutOfMemoryError异常或者是通过kill process 来杀掉部分进程以释放内存空间,当然如果被kill点关键的进程的话,也就可能导致部分应用会自动的退出。出现该情况时,主要是在进行频繁的进行大量的操作导致的,所以使用手动的方式也是可能进行重现的。

 

3)详细分析monkey日志:

将执行Monkey生成的log导出并打开查看该log;在log的最开始都会显示Monkey执行的seed值、执行次数和测试的包名。

info.txt:

***************************************

:Monkey: seed=1 count=100000

:AllowPackage: com.avatar.settings

 

分析log中的具体信息,方法如下:

查看log中第一个Switch,主要是查看Monkey执行的是哪一个Activity,譬如下面的log中,执行的是com.avatar.settings/.Settings,在下一个swtich之间的,如果出现了崩溃或其他异常,可以在该Activity中查找问题的所在

***************************************

:Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.avatar.settings/.Settings;end

// Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.avatar.settings/.Settings } in package com.avatar.settings

 

在下面的log中,Sending Pointer ACTION_DOWN和Sending Pointer ACTION_UP代表当前执行了一个单击的操作;

***************************************

:Sending Key (ACTION_DOWN): 167    // KEYCODE_CHANNEL_DOWN

:Sending Key (ACTION_UP): 167    // KEYCODE_CHANNEL_DOWN

 

Sleeping for 200 milliseconds这句log是执行Monkey测试时,throttle设定的间隔时间,每出现一次,就代表一个事件

***************************************

Sleeping for 200 milliseconds

 

SendKey(ACTION_DOWN) //KEYCODE_DPAD_DOWN   代表当前执行了一个点击下导航键的操作;

***************************************

:Sending Touch (ACTION_DOWN): 0:(1033.0,37.0)

:Sending Touch (ACTION_UP): 0:(1023.5691,57.83191)

 

Sending Pointer ACTION_MOVE     代表当前执行了一个滑动界面的操作

***************************************

Sending Trackball (ACTION_MOVE): 0:(1.0,-3.0)

 

如果Monkey测试顺利执行完成,在log的最后,会打印出当前执行事件的次数和所花费的时间;// Monkey finished代表执行完成。Monkey执行中断,在log的最后也能查看到当前已执行的次数。Monkey执行完成的log具体如下:

Events injected: 6000

:Dropped: keys=0 pointers=9 trackballs=0 flips=0

## Network stats: elapsed time=808384ms (0ms mobile, 808384ms wifi, 0msnot connected)

// Monkey finished

 

 

二、 自动化测试工具-monkeyrunner

 

1.4 Monkeyrunner简介

monkeyrunner即android SDK中自带的工具之一,此工具提供API可按制android设备或模拟器。monkeyrunner提供了一个API,使用此API写出的程序可以在Android代码之外控制Android设备和模拟器。通过monkeyrunner,可以写出一个Python程序去安装一个Android应用程序或测试包,运行它,向它发送模拟击键,截取它的用户界面图片,并将截图存储于工作站上。monkeyrunner工具的主要目的是用于测试功能/框架水平上的应用程序和设备,或用于运行单元测试套件,但您当然也可以将其用于其它目的。

 

 

1.5 Monkeyrunner工具特性

多设备控制:monkeyrunner API可以跨多个设备或模拟器实施测试套件。您可以在同一时间接上所有的设备或一次启动全部模拟器(或统统一起),依据程序依次连接到每一个,然后运行一个或多个测试。您也可以用程序启动一个配置好的模拟器,运行一个或多个测试,然后关闭模拟器。这里就是为什么我们要采用monkeyrunner进行自动化测试,因为我们的系统是需要机器人和监护人端进行交互,大部分用例是需要同时在机器人和监护人端的设备上进行,因此monkeyrunner可以进行多设备控制,正是适合我们项目的最好的自动化测试工具,则其他android自动化工具则无法达到这个目的。

功能测试:monkeyrunner可以为一个应用自动化功能测试。为您提供按键或触摸事件的输入数值,然后观察输出结果的截屏。       

回归测试:monkeyrunner可以运行某个应用,并将其结果截屏与既定已知正确的结果截屏相比较,以此测试应用的稳定性。       

可扩展的自动化:由于monkeyrunner是一个API工具包,您可以基于Python模块和程序开发一整套系统,以此来控制Android设备。除了使用monkeyrunner    API之外,您还可以使用标准的Python    ossubprocess模块来调用如adb这样的Android工具。

 

 

 

1.6 Monkeyrunner常用API

1.MonkeyRunner:这个类提供了用于连接monkeyrunner和设备或模拟器的方法,它还提供了用于创建用户界面显示提供了方法。

1) 手势

Void dragtuple start,tuple end,float duration,integer steps

通过drag()方法直接传入A点和B点的坐标即可进行拖拽操作

2) 点击

通过touch方法传入A点坐标,并通过DOWN_AND_UP参数直接完成点击

3)输入

Void typestring message

通过type()方法传入text进行输入

4) 启动应用

Void startActivity(string url,string action,string data,string mimetype,iterable categories,dictionary extras,component component,flags)

通过startActivity方法传入component(包名和应用名组合)即可启动该应用

5)等待

Void sleep(float seconds)

通过sleep()方法传入seconds(单位:秒)进行等待操作

6) 键值事件

Void pressstring name,dictionary type

通过press()方法发送namekeycode)和typeDOWN_AND_UP等)来处理键值事件

7) 输入

String input(string message,string initialvalue,string title,string oktitle,string canceltitle)

通过input()方法在PC端弹出输入框以供用户输入反馈

8) 选择列表框

Integer choice(string message,iterable choices,string title)

通过choice方法即可在PC端弹出选项列表以供用户选择

9) 警告框

Void alert(string message,string title,string oktitle)

通过alert()方法即可在PC端弹出警告框以提示用户

 

.MonkeyDevice:代表一个设备或模拟器。这个类为安装和卸载包、开启Activity、发送按键和触摸事件、运行测试包等提供了方法。

1 等待设备连接

monkeyDevice waitforconnectionfloat timeoutstring deviceid

通过waitforconnection()方法等待设备连接到PC,若连接失败,将不会继续进行后续步骤。

2 安装应用

Void installpackage(string path)

通过installpackage()方法将PC端应用安装到设备上

3)卸载应用

Void removepackage(string package)

通过removepackage()方法卸载设备端应用,并删除该应用数据

4)重启设备

Void reboot(string info)

通过reboot()方法即可重启设备,并在重启后选择需要进入的模式

5)唤醒设备

Void wake()

通过wake()方法即可唤醒设备

6)获取当前设备属性

Object getpropertystring key

通过getproperty即可获取设备属性

 

3MonkeyImage:这个类提供了捕捉屏幕的方法。这个类为截图、将位图转换成各种格式、对比两个MonkeyImage对象、将image保存到文件等提供了方法。

1)截屏

Monkeyimage takesnapshot()

通过monkeydevicestakesnapshot()方法即可获取当前屏幕图像

2)图形保存

通过writetofile()方法即可将截取图像保存为图片

Void writetofile(string path,string format)

3) 图像对比

boolean sameasmonkeyimage otherfloat percent

对比当前图像与对比图像是否一致

 

1.7 测试环境准备

  1)系统所用的语言是python,所有的测试库,脚本,框架均需要此语言编译器的环境,先在windows下安装python工具

  2)jython是python使用java语音的完全实现,系统需要和android交互,因此需要安装jython

 3)准备android开发环境,下载SDK工具包,包中有自动化测试工具monkeyrunner,以及获取控件信息工具hierarchyviewer,安卓调试工具ADB等

 

1.8 Monkeyrunner脚本编写

 

用例1:打开并连接wifi

***************************************

# -*- coding: UTF-8 -*-

#File:   wifi1.py

#用例:打开并设置无线网络

print 'Before execution'

#引入本程序所用到的模块

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage

#连接机器人设备

device=MonkeyRunner.waitForConnection()

if not device:  

        print "Please connect a device to start!"      

else:  

        print "Start "

#打开设置

device.startActivity(component = "com.avatar.settings/.Settings")

MonkeyRunner.sleep(2)

#打开无线网络

device.touch(935,262,'DOWN_AND_UP')

MonkeyRunner.sleep(2)

#打开wifi(TP_LINK_4E66)

device.touch(878,454,'DOWN_AND_UP')

MonkeyRunner.sleep(2)

#点击需要输入密码的文本框)

device.touch(530,860,'DOWN_AND_UP')

MonkeyRunner.sleep(2)

#字符串发送到键盘 

device.type('avatarmindtest123')

MonkeyRunner.sleep(2)

#点击键盘“完成”键

device.touch(1741,1020,'DOWN_AND_UP')

MonkeyRunner.sleep(2)

#点击"连接”按钮

device.touch(1375,186,'DOWN_AND_UP')

MonkeyRunner.sleep(3)

#截屏

result = device.takeSnapshot()

#图像保存

result.writeToFile('C:\\wifi1.png','png')

#关闭设置,回到首页

device.touch(152,153,'DOWN_AND_UP')

print ('success')

***************************************

 

查看该图表示用例是否成功执行,如下表示该用例测试pass。

 

用例2:对平板首页滑屏2次

***************************************

# -*- coding: UTF-8 -*-

#File:   huaping1.py

#用例:对平板首页滑屏2次

print 'Before execution'

#引入本程序所用到的模块

from com.android.monkeyrunner import MonkeyRunner

#连接机器人设备

device = MonkeyRunner.waitForConnection()

#截屏

result = device.takeSnapshot()

#保存图片

result.writeToFile('./beforeDrag.png','png')

#从右到左滑动屏幕2次

for i in range(0,2):

    device.drag((600,200),(100,200),0.1,12)

    MonkeyRunner.sleep(1)

#截屏

result = device.takeSnapshot()

#保存图片

result.writeToFile('./afterDrag.png','png')

print 'success'

***************************************

 

 

查看下面分别是beforeDrag.png和afterDrag.png,是否滑动成功,下图表示该用例执行pass

 

  

用例3:重复对监护人app做打开关闭操作5次

***************************************

# -*- coding: UTF-8 -*-

#File:   open1.py

#用例:重复对监护人app做打开关闭操作5次

print 'Before execution'

#导入方法

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

#连接设备

print ("Connecting device.....")

device = MonkeyRunner.waitForConnection()

if not Device:

    print ("Please connect a device to start!")

else:

    print ("Device Connected successfully!")

 

#安装apk

try:

    Device.installPackage('C:/apps/GuardianMobile.apk')

    print ("Package installed successfully! ")

except:

    print ("Package installation failed!")

 

#设置包名

package = 'com.avatarmind.guardians'

 

#设置activity名

activity = 'com.avatarmind.guardian.account.LoginActivity'

 

#循环执行四次

for i in range(1,5):

    #打开已安装的应用

    print ("Open installed package)

    device.startActivity(component = "com.avatarmind.guardians/com.avatarmind.guardian.account.LoginActivity")

    #等待5秒

    print ("wait 5 sec")

    MonkeyRunner.sleep(5)

    #关闭应用

    print("Quit the application")

    device.press('KEYCODE_BACK',MonkeyDevice.DOWN_AND_UP)

    print ("wait 5 sec")

    MonkeyRunner.sleep(5)

 

#卸载APK

try:

    print("Uninstall package!")

    Device.removePackage("com.avatarmind.guardians")

    print("Uninstall package successfully")

except:

print ("Package unintall failed!")

print 'success'

 

用例4:同时控制监护人端和机器人端的设备(视频通话,应用商城功能可用)

***************************************

# -*- coding: utf-8 -*-

#导入模块

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice

#连接机器人端,监护人端

Device1=MonkeyRunner.waitForConnection(5,"rk3288")

device2=MonkeyRunner.waitForConnection(5,"lianxiang")

#在监护人端安装APK

Device2.installPackage('E:/GuardianMobile.apk')

package='com.avatarmind.guardians'

activity='.com.avatarmind.guardian.account.LoginActivity'

runComponent=package+'/'+activity

#启动监护人端APK

Device2.startActivity(component=runComponent)

MonkeyRunner.sleep(5)

#操作监护人端某个点

Device2.press('KEYCODE_BACK',MonkeyDevice.DOWN_AND_UP)

.....

#再操作机器人端某个点

Device1.press('KEYCODE_BACK',MonkeyDevice.DOWN_AND_UP)

.....

***************************************

 

1.1 测试结果分析

   按照每条用例完成测试脚本的编写后,在python的环境中,执行该脚本,即可在自定义的图片存储位置查找图片,分析测试结果的方法就是查看图片,通过查看既定时刻的屏幕截图,即可知道平板在检查点处是否正确的完成了应该完成的功能,测试用例是否测试通过。

 

posted on 2022-06-13 17:30  宝宝萌  阅读(1445)  评论(0编辑  收藏  举报