android monkey原理_实现高速点击的 Android Monkey 自动化工具 fastmonkey - 代号 Maxim

打造一款快速高效且高度可复用的android自动化测试工具 (qq群 :608824162)

主页:

https://github.com/zhangzhao4444/Maxim

优势

高速点击,每秒 10-15 action!

多平台兼容! 同时兼容Android 5-8

轻量极简!

如何使用

adb push  framework.jar  monkey.jar  文件到 /sdcard

执行  adb shell CLASSPATH=/sdcard/monkey.jar:/sdcard/framework.jar exec app_process /system/bin tv.panda.test.monkey.Monkey -p com.panda.videoliveplatform --uiautomatormix --running-minutes 60

参数说明

tv.panda.test.monkey.Monkey 主调入口  无需修改

-p com.panda.videoliveplatform  待测appid

策略模式

--uiautomatormix 混合模式(70%控件解析随机点击,其余30%按原Monkey事件概率分布)

--pct-uiautomatormix n 可自定义混合模式中控件解析事件概率

--uiautomatordfs DFS深度遍历算法(优化版)(注 Android5不支持dfs)

非以上两种为原始Monkey策略

执行时长

--running-minutes 60        执行60分钟monkey

场景细粒度控制

--act-whitelist-file  /sdcard/awl.strings    自定义Activity白名单

例:com.panda.videoliveplatform.activity.WelcomeActivity

com.panda.videoliveplatform.activity.SplashWakeActivity

com.panda.videoliveplatform.activity.MainFragmentActivity

com.panda.videoliveplatform.activity.LiveRoomActivity

锁定跳转只可进入其中的某个Activity

--act-blacklist-file        同上

其他参数及用法同原始Monkey

特性简介

a. 速度快 每秒10-15个Action事件

界面控件解析算法通过改造底层framework,直接使用AccessibilityNodeInfo并优化减化其调度流程,解析速度控制在50ms内,可对界面变化做快速反应。

{

val clickable = ArrayList()

collectClickable(clickable, root)   //递归算法生成node树结构    ......

val node = clickable[random.nextInt(count)]

val nodeRect = Rect()

node.getBoundsInScreen(nodeRect)  //选取其中某个node的 rect ,随机点击其中某point

generateClickEventAt(nodeRect, 0L)}

b. Android全平台兼容

兼容Android5,6,7,8各系列。通过反射原理动态解析各平台Api差异,使用一套逻辑兼容全系列。

{

Class> clazz = mAm.getClass();

String name = "setActivityController";    //存在差异的api

Method method = findMethod(clazz, name, android.app.IActivityController.class);     //反射动态search api

if (method != null) {

......

}

method = findMethod(clazz, name, android.app.IActivityController.class, boolean.class);

if (method != null) {

......}

c. 防跳出

控件解析时获取进程推栈Top Activity,按非白即黑立即执行切回。各事件执行时按特有逻辑屏蔽掉状态栏,防止误操作。

{

......

cn = this.mDevice.mAm.getTasks(1, 0).get(0).topActivity    //取top activity     if (cn != null) currentPackage = cn.getPackageName()

if (!MonkeyUtils.packageFilter.isPackageValid(currentPackage!!)) {    //判断非白即黑         this.mQ.clear()

this.generateActivity()

......}

d. 防休眠

休眠时自动检测并唤醒屏幕。

{

......

if (!this.mPM!!.isInteractive) {      //判断处于休眠中        ......

val i = Runtime.getRuntime().exec(arrayOf("input", "keyevent", "26")).waitFor()    //唤醒设备    ......}

e. 熔断机制

当事件按某个特有模式固定执行一段时间时则自动触发熔断开始自拉活,防止假死。如重复点击同一位置n秒。

private fun isBlocked(): Boolean{

val jam = true

......

val last = actionsHistory.last()

for (i in 2..30){    //重复点击n次 触发熔断

if (mVerbose > 1)

Logger.log("last action is ${actionsHistory.size-1} code = $last, action${actionsHistory.size-i} code = ${actionsHistory[actionsHistory.size-i]}")

if (last != actionsHistory[actionsHistory.size-i]){

return false

}

}

//其他熔断    .....}

f. 场景细粒度

引入Activity黑白名单,可控制限定在某些场景内。如只测试某几个相关页面。

private inner class ActivityController : IActivityController.Stub() {

override fun activityStarting(intent: Intent, pkg: String): Boolean {

var allowActivity = true

if (MonkeyUtils.activityFilter.hasValidActivitys()){

val currentActivity: String? = try {intent.component.className} catch (e:Exception){null}

if (currentActivity != null){

allowActivity = MonkeyUtils.activityFilter.checkEnteringActivity(currentActivity)     //通过filter的才允许跳转            }

Logger.log("// Activity : ${currentActivity} in Intent")

}

......

}

......}

g. 随机自动输入

检测当遇到可输入模式时,按设定(ape.string)或随机输入键盘事件。如输入666或2333弹幕

随机输入 需要提前安装adbkeyboard

https://github.com/senzhk/ADBKeyBoard

{

......

val inputMethodVisbleHight = this.mDevice.mIMM!!.getInputMethodWindowVisibleHeight()    //存在键盘输入栏

if (inputMethodVisbleHight <= 0) return

//注入键盘事件

try { generateRandomKeyEvents() }catch (e : Exception){ }

......}

h. 崩溃堆栈自动保存

当崩溃(crash、oom)发生时自动抓取,并存于/sdcard/crash-dump.log

{

override fun appCrashed(processName: String, pid: Int, shortMsg: String, longMsg: String, timeMillis: Long, stackTrace: String): Boolean {

......

writeDumpLog("// CRASH: $processName (pid $pid) (dump time: $dateStr)")

writeDumpLog("// Build Time: ${Build.TIME}")

writeDumpLog("// ${stackTrace.replace("\n", "\n// ")}")            ....}

todo

特殊事件序列

引入GT性能测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值