monkey是只皮猴子,是安卓中的一个UI压力测试工具,重在测试稳定性。但是在运用monkey测试app,深受其乱点的烦恼,虽然在指定app的情况下,依然会随机点到app外面,然后再也回不来了,大大降低了其作用。
查阅了网上不少文章,在看这篇文章的时候,突然有了点启发https://blog.csdn.net/liyu520131414/article/details/6935777
这篇文章的思路就是在monkey在执行时候,另外开启一个程序对其进行轮询,如果不在指定的页面,就随机将它拉到app里指定的页面。
当然java我不太懂,只是大致看了下,在执行的时候也没有达到理想的效果,也许是我执行的方式不对,因此参照他的思路,用python写了个轮询脚本,当然功能上也比他写的缩减了不少,暂时只是对连接在电脑上一台手机进行此操作,详细优化步骤如下。
1.monkey脚本
先来看下原先我们执行的脚本
adb shell monkey -p cn.citytag.mapgo -s 2333 --pct-touch 70 --pct-motion 30 --ignore-crashes --ignore-timeouts --monitor-native-crashes --throttle 200 -v -v 500000 >E:\logs\monkey0903.txt
monkey命令的含义就不细说了,网上有超多文章进行了详细解释,绿色--pct-touch 70 --pct-motion 30这两个命令是后面增加的,一个代表点击,一个代表滑动,两个加起来是100,代表不会进行其他事件操作,如轨迹事件,导航事件等等,指定这两种操作后,就极大的降低了monkey点到被测app外面的概率
另外还是会有在执行向下滑动的命令时,打开了通知栏,然后又开始了瞎点的操作。这时可在执行monkey命令之前,先执行禁用通知栏的命令
adb shell settings put global policy_control immersive.full=*
解禁命令:adb shell settings put global policy_control null
2.python脚本
在完善了monkey脚本之后,还是会出现monkey点出去之后回不来的情况,那就写脚本吧。
首先再一次明确目标,就是在monkey乱点点出了被测app后将其拉回来。
直接先把代码丢上来。之前参照的文章里面利用xml作为配置文件,感觉挺简单的,也就直接用了。
配置文件:config.xml
<?xml version="1.0" encoding="utf-8"?>
<config>
<!-- 包名-->
<packagename>com.alashow.live</packagename>
<!-- 主activity-->
<mainactivity>.MainActivity</mainactivity>
<!-- 白名单activity-->
<whiteactivity>
/.MainActivity,
/cn.citytag.live.view.activity.LivePlayerActivity,
/user.maopao.com.user.view.activity.mine.OthersHomePageActivity,
/cn.citytag.live.view.activity.LiveFinishActivity,
/cn.citytag.live.view.activity.LiveSearchActivity,
/cn.citytag.live.view.activity.LiveRankingActivity,
/cn.citytag.live.view.activity.LiveSubHomeActivity,
/cn.citytag.live.view.activity.family.FamilyDetailActivity,
/cn.citytag.live.view.activity.family.FamilyInformActivity,
/cn.citytag.live.view.activity.family.FamilySettingActivity,
/cn.citytag.live.view.activity.family.FamilyNoticeActivity,
/cn.citytag.live.view.activity.tribe.TribeHomeActivity,
/cn.citytag.live.view.activity.tribe.TribeWelfareActivity,
/cn.citytag.live.view.activity.tribe.TribeShopActivity,
/cn.citytag.live.view.activity.tribe.TribePackageActivity,
/user.maopao.com.user.view.activity.bill.MyIncomeTotalDetailActivity,
/cn.citytag.live.view.activity.LivePrepareActivity,
/cn.citytag.live.view.activity.LiveSongEditActivity,
/cn.citytag.live.view.activity.LiveNoticeActivity,
/cn.citytag.base.widget.pictureselector.lib.PictureSelectorActivity
</whiteactivity>
<!-- 检查时间秒-->
<interval>30</interval>
<!-- 检查次数-->
<count>10</count>
</config>
说明:没什么好说明的,都注释出来了,就是字面意思。
python脚本:
import os
import re
import xml.dom.minidom as xmldom
import time
class Mtest():
def __init__(self):
dom = xmldom.parse('config.xml')
root = dom.documentElement
self.packagename = root.getElementsByTagName('packagename')[0].firstChild.data
self.mainactivity = root.getElementsByTagName('mainactivity')[0].firstChild.data
self.interval = int(root.getElementsByTagName('interval')[0].firstChild.data)
self.count = int(root.getElementsByTagName('count')[0].firstChild.data)
self.whiteactivity = root.getElementsByTagName('whiteactivity')[0].firstChild.data.replace('\n','').replace(' ','').split(',')
def get_now_activity(self):
os.system("adb devices")
content = os.popen('adb shell dumpsys activity |findstr "mResumedActivity" ').read() #读取当前页面
pattern = re.compile(r'/[a-zA-Z0-9\.]+')
alist = pattern.findall(content)
macitivity = self.packagename + '/' + self.mainactivity
excuteshell = 'adb shell am start -n'+ macitivity
if alist[0] not in self.whiteactivity:
print('当前activity:'+alist[0])
print('--------------开始返回主activity----------------')
os.system(excuteshell) #可拉回主页面
else:
print('当前activity:'+alist[0]+'不需要返回')
def check(self):
for _ in range(self.count):
time.sleep(self.interval)
self.get_now_activity()
if __name__ == '__main__':
test = Mtest()
test.check()
python脚本这里就要稍微说明下了:
1.这里造了一个类,类的初始化里将config.xml里的内容读取过来运用了xml的一个库
2.get_now_activity函数的作用是获取当前所在activity,判断其是否在白名单里,如果在就做操作,如果不在就拉回主页面(当然你可以设置拉回任何页面,甚至随机)
os.system("adb devices") 这句不写也没关系,其实是获取当前连接的手机设备信息
adb shell dumpsys activity |findstr "mResumedActivity" 这条adb命令就是获取当前所在activity。如果你查看app的activity也很简单,你手机连着执行这条命令就可以了,这条命令执行后大致是这样的结果:
是不是数据不够单纯,与config.xml里的白名单数据相比是不是多了很多东西。
pattern = re.compile(r'/[a-zA-Z0-9\.]+')
alist = pattern.findall(content)
这时候可以用正则表达式将其取出输出alist[0],大致是这样的:
页面取出来之后就可以对其进行对比了,就是那个if判断
接下来就是在判断到activity不在白名单里面之后,启动指定activity 利用这个命令'adb shell am start -n'
3.最后一个函数就是利用config.xml里的配置,设置多长时间去轮询一次,然后一共轮询多少次。如30s轮询一次,那么一个小时就能轮询120次,假设你的monkey执行10个小时,那么你的轮询次数就要设置1200次。
说了这么多,如何执行呢?
1.先执行adb monkey的命令,将monkey跑起来
2.执行python脚本
3.仔细观察是不是就算monkey乱点也能拉回去了呢,<(* ̄▽ ̄*)/