(无需 Root) 基于 Android Monkey 二次开发,实现高速点击的 Android Monkey 自动化工具 fastmonkey – 代号 Maxim

random
random
random
订阅者
10318
文章
0
粉丝
测试交流200542字数 1266阅读4分13秒阅读模式

打造一款快速高效且高度可复用的 android 自动化测试工具

主页入口 请点我https://github.com/zhangzhao4444/Maxim

(无需 Root) 基于 Android Monkey 二次开发,实现高速点击的 Android Monkey 自动化工具 fastmonkey – 代号 Maxim-图片1

优势

  1. 高速点击,每秒 10-15 action!
  2. 多平台兼容! 同时兼容 Android 5-9
  3. 轻量极简!

如何使用

  1. adb push framework.jar monkey.jar 文件到 /sdcard
  2. 执行
    adbshell 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

    脱机运行(#53 楼)

参数说明

  1. tv.panda.test.monkey.Monkey 主调入口 无需修改
  2. -p com.panda.videoliveplatform 待测 appid
  3. 策略模式

    --uiautomatormix 混合模式(70% 控件解析随机点击,其余 30% 按原 Monkey 事件概率分布)
    --pct-uiautomatormix n 可自定义混合模式中控件解析事件概率
    --uiautomatordfs DFS 深度遍历算法(优化版)(注 Android5 不支持 dfs)
    --uiautomatortroy Troy 模式 见(#74 楼)
    非以上两种为原始 Monkey 策略

  4. 执行时长
    --running-minutes 60 执行 60 分钟 monkey

  5. 场景细粒度控制
    --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 同上

  6. 其他参数及用法同原始 Monkey

特性简介

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

{
val clickable = ArrayList<AccessibilityNodeInfo>()
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,p 各系列。通过反射原理动态解析各平台 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

  1. 特殊事件序列 - 已完成
  2. 引入 GT 性能测试
  3. 控件黑名单 - 已完成
  4. xposed 模式 --见 xmonkey
  5. Ai 算法 模式

** 其他 **

扫盲贴: https://testerhome.com/topics/11884

常见问题排查

  1. 小米手机未开启 “开发者选项” -> "USB 调试(安全设置)允许通过 usb 调试修改权限或模拟点击"。
    开启后 ok 。报错 log 如下图

    (无需 Root) 基于 Android Monkey 二次开发,实现高速点击的 Android Monkey 自动化工具 fastmonkey – 代号 Maxim-图片2

  2. accessibilityservice 被其他驱动占用 agent 未注销。如使用过 atx 未执行 unregister。
    执行 unregister 后 OK。报错 log 如下图,或无 log

    (无需 Root) 基于 Android Monkey 二次开发,实现高速点击的 Android Monkey 自动化工具 fastmonkey – 代号 Maxim-图片3



  3. 厂商修改造成 dex 无法 load ,maxim 启动后就退出。实际什么都未执行。无 log 输出。 logcat 如下图。此问题暂时待查

    (无需 Root) 基于 Android Monkey 二次开发,实现高速点击的 Android Monkey 自动化工具 fastmonkey – 代号 Maxim-图片4

4.运行 maxim 无任何 log,启动后就退出。需检查/sdcard/是否存在 monkey.jar ,framework.jar。部分机型发现 adb push 过去 monkey.jar 自动被更名成 monkey. 导致无法运行。

(无需 Root) 基于 Android Monkey 二次开发,实现高速点击的 Android Monkey 自动化工具 fastmonkey – 代号 Maxim-图片5

5.vivo7.1 运行 maxim 报错,需要关闭锁屏和开启 usb 模拟点击 ,然后就可以跑 monkey 了。报错如下:

(无需 Root) 基于 Android Monkey 二次开发,实现高速点击的 Android Monkey 自动化工具 fastmonkey – 代号 Maxim-图片6

update

#40 楼
支持特殊事件序列 max.xpath.actions
如何查看特殊事件 log #79 楼

#44 楼 #52 楼
支持屏蔽黑控件或黑区域 max.widget.black

#57 楼
支持截图,dump xml
崩溃回溯式截图 #92 楼

#74 楼
Troy 模式

#169 楼
Monkeyapi

 
评论  200  访客  200
    • 东子
      东子 9

      android5.1,加入特殊事件序列后,执行,一到特殊事件序列的 activity,monkey 就停止了

      • zhangzhao_lenovo
        zhangzhao_lenovo 9

        2018.02.28 update

        支持黑控件 黑区域屏蔽(mix dfs troy 均支持)

        配置 max.widget.black
        案例
        [
        {
        “activity”:”com.panda.videoliveplatform.activity.MainFragmentActivity”,
        “xpath”: “//*[@class=’android.widget.TextView’ and @text=’我的校园’ and @resource-id=’com.panda.videoliveplatform:id/tv_title’]”
        },
        {
        “activity”:”com.panda.videoliveplatform.activity.MainFragmentActivity”,
        “xpath”: “//*[@class=’android.widget.TextView’ and @text=’车队’ and @resource-id=’com.panda.videoliveplatform:id/tv_title’]”,
        “index”: 0,
        “bounds”: “[0,633][900,789]”
        },
        {
        “activity”:”com.panda.videoliveplatform.activity.MainFragmentActivity”,
        “bounds”: “[0,1107][900,1263]”
        }
        ]

        当且仅当 当前 activity == 所配 activity 或未配 activity 时 做黑检查
        三种方式:
        1.仅配置 bounds
        屏蔽某个区域,在该区域内的控件或坐标不会被点击。
        2.配置 xpath
        查找匹配的控件,屏蔽点击该控件。
        3.xpath+bounds
        查找匹配的控件,当控件存在时屏蔽指定的区域。

        注 配置完成后请贴在 json.cn 检查格式,注意” : , 非中文
        将该文件 push 到 /sdcard/max.widget.black

        • zhangzhao_lenovo
          zhangzhao_lenovo 9

          帮助文档里有写这个,配置命名我规范了下 之前太随意了

          • 老马
            老马 9

            更新后 发现
            是 ape.strings 对应现在的 max.strings
            ape.xpath.actions 对应现在的 max.xpath.actions

            还多了一个 max.config 是配置什么的
            cmd@TR:~/workspace/git/Maxim$ cat max.config
            max.startAfterNSecondsofsleep = 6000
            max.wakeupAfterNSecondsofsleep = 4000

            • zhangzhao_lenovo
              zhangzhao_lenovo 9

              2018.02.23 update

              增加支持 特殊事件序列(mix dfs troy 均支持)

              需要配置 max.xpath.action 文件
              案例:
              [
              {
              “prob”: 1,
              “activity”:”tv.panda.account.activity.WebLoginActivity”,
              “actions”: [
              {
              “xpath”: “//*[@class=’android.widget.EditText’]”,
              “action”: “INPUTTEXT”,
              “text”: “13810751000”,
              “index”: 0,
              “throttle”: 300
              },
              {
              “xpath”: “//*[@class=’android.widget.EditText’]”,
              “action”: “INPUTTEXT”,
              “text”: “123400”,
              “index”: 1,
              “throttle”: 300
              },
              {
              “xpath”: “//*[@content-desc=’登录’ and @class=’android.view.View’]”,
              “index”: 0,
              “action”: “CLICK”,
              “throttle”: 1000
              }]
              },
              {
              “prob”: 1,
              “actions”: [
              {
              “xpath”: “//*[@class=’android.view.View’]”,
              “index”: 0,
              “action”: “SWIPE”,
              “args”: “10,1000,800,1000,100”,
              “throttle”: 3000
              }]
              },
              {
              “prob”: 1,
              “actions”: [
              {
              “xpath”: “//*[@class=’android.view.View’]”,
              “index”: 0,
              “action”: “TOUCH”,
              “args”: “500,1000”,
              “throttle”: 1000
              }]
              },
              {
              “prob”: 1,
              “actions”: [
              {
              “xpath”: “//*[@class=’android.view.View’]”,
              “index”: 0,
              “action”: “KEYEVENT”,
              “keycode”: 4,
              “throttle”: 1000
              }]
              }
              ]

              上述包含 3 个特殊事件
              发生概率 prob =1 为 100% 发生
              仅当 当前 activity 为 tv.panda.account.activity.WebLoginActivity 时或无 activity 配置时做事件查找
              xpath 为待查找控件的 xpath 支持复杂型 xpath,支持 index 索引选择
              throttle 为该特殊步骤执行完后 sleep n 毫秒
              Action 支持
              1.Click 点击匹配到的 xpath 控件
              2.INPUTTEXT 在匹配到的 xpath 控件中输入 text 指定字符,输入需要提前安装 adbkeyboard
              3.TOUCH 点击指定坐标 args = (x,y)
              4.SWIPE 按执行路径滑动 args = (x1,y1,x2,y2,step)
              5.KEYEVENT 执行键盘事件 keycode

              注 配置完成后请贴在 json.cn 检查格式,注意” : , 非中文
              将该文件 push 到 /sdcard/max.xpath.actions
              如果要执行的一个事件序列,执行过程中会出现 activity 跳转,则应该将该序列拆分成两个 actions 进行配置。

              • zhangzhao_lenovo
                zhangzhao_lenovo 9

                qq 群 :608824162

                • zhanglimin
                  zhanglimin 9

                  方便给下群号吗 我也想加群 了解下,自带的 monkey 太随机了

                  • 寒月守护
                    寒月守护 9

                    “USB 调试(安全设置)允许通过 usb 调试修改权限或模拟点击”这个打开后就可以了,给力!

                    • zhangzhao_lenovo
                      zhangzhao_lenovo 9

                      “开发者选项” -> “USB 调试(安全设置)允许通过 usb 调试修改权限或模拟点击” 这个可否打开了?

                      • zhangzhao_lenovo
                        zhangzhao_lenovo 9

                        不需要 root

                      匿名

                      发表评论

                      匿名网友
                      确定

                      拖动滑块以完成验证