https://blog.csdn.net/weixin_45912307/article/details/109393436
1. 业务背景
2. 解决思路
3. 自动遍历技术
4. 常用遍历工具
1. monkey命令
adb shell monkey [options]
事件计数adb shell monkey -help
查看帮助命令adb shell monkey n
对所有包随机操作adb shell monkey -p com.android.settings n
对指定包运行n次adb shell monkey -p com.android.settings -s m n
adb shell monkey -p com.android.settings -vv n
打印详细日志adb shell monkey -p com.android.settings --throttle t n
延迟时间tadb shell monkey -p com.android.settings --xx事件 m n
在运行n次中xx事件共执行m次2. 常用事件
--pct-touch
触摸事件,如点击
--pct-motion
动作时间,如滑动(直线)
--pct-trackball
轨迹事件,如移动+点击,曲线滑动
--pct-majornav
主要导航事件,如回退按钮、菜单按钮
3. 案例
对Android Monkey的改造,基于遍历规则的高性能Android Monkey,适用于真机/模拟器的APP UI压力测试
adb push framework.jar /sdcard
adb push 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 -v -v
tv.panda.test.monkey.Monkey
: monkey入口类,不要修改com.panda.videoliveplatform
: 被测app包名,需要修改,如本次案例使用的是同花顺app(com.hexin.plat.android)--uiautomatormix
: 遍历策略1. 模式 Mix (基于事件概率的压力测试)
--uiautomatormix
accessibiltyserver
获取界面接口 解析各控件,随机选取一个控件执行touch操作。accessibilityserver action
占比50%,其余各action分剩余的50%accessibilityserver action
占比可配置 --pct-uiautomatormix n
2. 模式 DFS
--uiautomatordfs
深度遍历算法3. 模式Troy
--uiautomatortroy
控件选择策略按max.xpath.selector
配置的高低优先级来进行深度遍历4. 保留原始monkey
5. 总运行时长 --running-minutes n
运行n分钟
6. --act-whitelist-file /sdcard/awl.strings
定义白名单 --act-blacklist-file
7. 其他参数与原始monkey一致
adb push framework.jar /sdcard
adb push monkey.jar /sdcard
adb shell dumpsys window w | findstr mCurrent
adb shell CLASSPATH=/sdcard/monkey.jar:/sdcard/framework.jar exec app_process /system/bin tv.panda.test.monkey.Monkey -p com.hexin.plat.android --uiautomatormix --running-minutes 1 -v -v
apprawler地址:https://github.com/seveniruby/AppCrawler
1. apprawler 底层引擎
- appium
- adb
- macaca
- selenium
2. appiu底层引擎
java -jar 包名
appcrawler --capability "appPackage=包名,appActivity=activity名"
1. 参数模式
java -jar appcrawler.jar 路径| --demo
appcrawler --capability "appPackage=包名,appActivity=activity名
2. 配置文件[推荐方式]
java -jar
--capability 'appPackage=包名,appActivity=activity名' \
-o 存放路径
capability
设置与appium完全一致testcase
:用于启动app后的基础测试用例selectedList
:遍历范围设定triggerActions
:特定条件触发执行动作的设置appPackage
:“”appActivity
:“”appium
:“http://127.0.0.1:4723/wd/hub”noReset
:trueautomationName
:uiautomator2donStopAppOnReset
:truegiven
:所有的先决条件when
:先决条件成立后的行为then
:断言集合testcase
的简写形态 xpath
:对应when里的xpathaction
:对应when的action- back
:后退
backApp
回退到当前的app 默认等价于back行为可定制monkey
:随机事件 xxx()
:执行代码Thread.sleep( ts)
:线程等待,单位毫秒driver.swipe(0.9,0.5,0.1 , 0.5)
:滑屏click
:点击 longTap
:长触摸selectedList
:需要被遍历的元素范围firstList
:优先被点击lastList
:最后被点击tagLimitMax
:同祖先(同类型)的元素最多点击多少次backButton
:当所有元素都被点击后默认后退控件定位blackList
:黑名单maxDepth
:遍历的最大深度为10不要用nodpad++修改,可以用pycharm
adb logcat |findstr -i displayed
java -jar appcrawler-2.7.4-hogwarts.jar --demo -e GBK # 不编码为utf-8在运行的时候会报编码错误
java -jar appcrawler-2.7.4-hogwarts.jar -c demo.yaml
6. 遍历指定模块下的元素
selectedList:- xpath: "//androidx.recyclerview.widget.RecyclerView[contains(@resource-id,'rv_item_list')]//*[@clickable='true']"- xpath: "//android.widget.LinearLayout[contains(@resource-id,'entry_grid_layout')]//*[@clickable='true']"- xpath: "//android.widget.HorizontalScrollView[contains(@resource-id,'tablayout')]//*[@clickable='true']"
firstListDescription: "首先遍历"
firstList:- xpath: "//*[contains(@resource-id,'rv_item_list')]//*[@clickable='true']"
lastListDescription: "最后遍历"
lastList:- xpath: "//android.widget.LinearLayout[contains(@resource-id,'tab_widget')]//*[@clickable='true']"
---
capabilityDescription: "appium的capability通用配置,其中automationName代表自动化的驱动引擎,除了支持appium的所有引擎外,额外增加了adb和selenium的支持"
capability:appActivity: "com.hexin.plat.android.AndroidLogoActivity"appium: "http://127.0.0.1:4723/wd/hub"noReset: "true"dontStopAppOnReset: "false"appPackage: "com.hexin.plat.android"fullReset: "false"
waitAppLoadedTimeoutDescription: "等待加载超时时间"
waitAppLoadedTimeout: 10000
waitAppLoadedDescription: "需等待加载的元素"
waitAppLoaded:
- given: []when: nullthen: []xpath: "//*[contains(@text, 'App')]"action: ""actions: []times: -1
implicitlyWaitTestCaseDescription: "隐式等待测试用例"
implicitlyWaitTestCase: 3000
implicitlyWaitCrawlDescription: "隐式等待爬虫"
implicitlyWaitCrawl: 0
testcaseDescription: "测试用例设置,用于遍历开始之前的一些前置操作,比如自动登录"
testcase:name: "AppCrawler TestCase"steps:- given: []when: nullthen: []xpath: "/*/*"action: "Thread.sleep(1000)"actions: []times: -1
maxTimeDescription: "最大运行时间"
maxTime: 10800
maxDepthDescription: "默认的最大深度10, 结合baseUrl可很好的控制遍历的范围"
maxDepth: 10
selectedListDescription: "默认遍历列表,只有出现在这个列表里的控件范围才会被遍历"
selectedList:- xpath: "//androidx.recyclerview.widget.RecyclerView[contains(@resource-id,'rv_item_list')]//*[@clickable='true']"- xpath: "//android.widget.LinearLayout[contains(@resource-id,'entry_grid_layout')]//*[@clickable='true']"- xpath: "//android.widget.HorizontalScrollView[contains(@resource-id,'tablayout')]//*[@clickable='true']"
firstListDescription: "首先遍历"
firstList:- xpath: "//*[contains(@resource-id,'rv_item_list')]//*[@clickable='true']"
lastListDescription: "最后遍历"
lastList:- xpath: "//android.widget.LinearLayout[contains(@resource-id,'tab_widget')]//*[@clickable='true']"
triggerActionsDescription: "在遍历过程中需要随时处理的一些操作,比如弹框、登录等"
triggerActions:
- given: []when: nullthen: []xpath: "permission_allow_button"action: ""actions: []times: 3
- given: []when: nullthen: []xpath: "允许"action: ""actions: []times: 3
blackListDescription: "黑名单列表 matches风格, 默认排除内容包含2个数字的控件"
blackList:
- given: []when: nullthen: []xpath: ".*[0-9]{2}.*"action: ""actions: []times: -1
- given: []when: nullthen: []xpath: "Get Music"action: ""actions: []times: -1
backButtonDescription: "后退按钮列表,默认在所有控件遍历完成后,才会最后点击后退按钮。目前具备了自动判断返回按钮的能力,默认不需要配置"
backButton:
- given: []when: nullthen: []xpath: "Navigate up"action: ""actions: []times: -1
xpathAttributesDescription: "在生成一个控件的唯一定位符中应该包含的关键属性"
xpathAttributes:
- "name()"
- "name"
- "label"
- "value"
- "resource-id"
- "content-desc"
- "text"
- "id"
- "name"
- "innerText"
- "tag"
- "class"
sortByAttributeDescription: "陆续根据属性进行遍历排序微调,depth表示从dom中最深层的控件开始遍历,list表示dom中列表优先,selected表示菜单最后遍历,这是默认规则,一般不需要改变"
sortByAttribute:
- "depth"
- "list"
- "selected"
findByDescription: "默认生成控件唯一定位符的表达式风格,可选项 default|android|id|xpath,默认会自动判断是否使用android定位或者ios定位"
findBy: "xpath"
baseUrlDescription: "设置一个起始点,从这个起始点开始计算深度,比如默认从登录后的界面开始计算"
baseUrl: []
appWhiteListDescription: "app白名单,允许在这些app里进行遍历"
appWhiteList: []
urlBlackListDescription: "url黑名单,用于排除某些页面的遍历"
urlBlackList: []
urlWhiteListDescription: "url白名单,仅在这些界面内遍历"
urlWhiteList: []
beforeRestartDescription: "启动一个app默认等待的时间"
beforeRestart: []
beforeElementDescription: "在遍历每个控件之前默认执行的动作"
beforeElement: []
afterElementDescription: "在遍历每个控件之后默认执行的动作"
afterElement: []
afterElementWaitDescription: "在遍历每个控件之后默认等待的时间,用于等待新页面加载"
afterElementWait: 1000
afterAllDescription: "在遍历完当前页面内的所有控件后,是否需要刷新或者滑动"
afterAll: []
afterAllMaxDescription: "fterAll的最大重试次数,比如连续滑动2次都没新元素即取消"
afterAllMax: 2
tagLimitMaxDescription: "相似控件最多点击几次"
tagLimitMax: 20
tagAttributesDescription: "标签属性列表"
tagAttributes:
- "name()"
- "name"
- "label"
- "resource-id"
- "content-desc"
- "id"
- "name"
- "tag"
- "class"
tagLimitDescription: "设置部分相似控件的最大遍历次数"
tagLimit:
- given: []when: nullthen: []xpath: "确定"action: ""actions: []times: 1000
- given: []when: nullthen: []xpath: "取消"action: ""actions: []times: 1000
- given: []when: nullthen: []xpath: "share_comment_guide_btn_name"action: ""actions: []times: 1000
- given: []when: nullthen: []xpath: "//*[contains(@class, 'List')]//*"action: ""actions: []times: 2
assertGlobalDescription: "全局断言"
assertGlobal: []
suiteNameDescription: "报告中的测试套件名字可以由列表内的控件内容替换,增强报告中关键界面的辨识度"
suiteName:
- "//*[@selected='true']//android.widget.TextView/@text"
screenshotDescription: "是否截图"
screenshot: true
reportTitleDescription: "报告的title"
reportTitle: "同花顺首页自动化遍历"
resultDirDescription: "结果目录,如果为空会自动创建对应时间戳_报名的结果目录"
resultDir: ""
showCancelDescription: "是否展示跳过的控件记录"
showCancel: true
pluginListDescription: "插件列表,暂时禁用,太高级了,很多人不会用"
Description: "在selectedList firstList lastList等很多配置中,需要填充的是测试步骤Step类型。Step类型由given(满足条件)when(条件满足的行为)then(断言)三部分组成。Step可以简化为xpath(定位表达式,支持xpath 正则 包含关系)与action(点击输入等行为)"
pluginList: []