目录
appcrawler介绍
下载与启动
配置文件启动
appcrawler介绍
- 一个基于自动遍历的app爬虫工具. 支持android和iOS, 支持真机和模拟器. 最大的特点是灵活性. 可通过配置来设定遍历的规则.
优点
- 跨平台性:
AppCrawler
是基于appium
开发的,所以支持Android
和IOS
- 可控性:对测试的页面,控件类型的选择,测试的深度等都可自由控制
- 可定制:可自定义操作,如输入,滑动等
缺点
- 运行速度较慢:
AppCrawler
是基于appium
开发具备了跨平台的优点,但是也因为这层封装造成了运行速度相对较慢 - 使用门槛高:正因为使用灵活性的问题,也造成了使用门槛的提高,主要基于
yaml
文件中使用appium
的相关技术知识进行配置,这就对使用者有了一定的技术要求
下载与启动
下载
启动
说明:需要 java和appium环境
- step1 :启动appium : appium --session-override
- step2:启动appcrawler :java -jar appcrawler-2.4.0-jar.jar --capability "appPackage=com.taobao.taobao,appActivity=com.taobao.tao.welcome.Welcome" -o result
- 遍历原则:它的遍历原则是,找页面的里层次最深的元素,也就是处于中心位置元素会被优先遍历
- 测试结果:如果没有使用
-o
参数指定log输出的路径,appcrawler
就会在当前目录下生成以时间为命名的文件夹,里面保存了所有的数据,文件、截图、log - 测试报告:在测试log中有一个index.html文件,打开它会看到刚才运行的测试报告
配置文件启动
step1:生成配置文件模板:java -jar appcrawler-2.4.0-jar.jar --demo
- 配置文件demo.yml如下
---
pluginList: []
saveScreen: true
reportTitle: ""
resultDir: "20210307174024"
waitLoading: 500
waitLaunch: 6000
showCancel: true
maxTime: 10800
maxDepth: 10
capability:
noReset: "true"
fullReset: "false"
appium: "http://127.0.0.1:4723/wd/hub"
testcase:
name: "TesterHome AppCrawler"
steps:
- given: []
when: null
then: []
xpath: "/*"
action: "Thread.sleep(5000)"
actions: []
times: 0
selectedList:
- given: []
when: null
then: []
xpath: "//*[contains(name(), 'Button')]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[contains(name(), 'Text') and @clickable='true' and string-length(@text)<10]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[@clickable='true']/*[contains(name(), 'Text') and string-length(@text)<10]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[contains(name(), 'Image') and @clickable='true']"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[@clickable='true']/*[contains(name(), 'Image')]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[contains(name(), 'Image') and @name!='']"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[contains(name(), 'Text') and @name!='' and string-length(@label)<10]"
action: null
actions: []
times: 0
firstList: []
lastList:
- given: []
when: null
then: []
xpath: "//*[@selected='true']/..//*"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[@selected='true']/../..//*"
action: null
actions: []
times: 0
backButton:
- given: []
when: null
then: []
xpath: "Navigate up"
action: null
actions: []
times: 0
triggerActions:
- given: []
when: null
then: []
xpath: "share_comment_guide_btn"
action: null
actions: []
times: 0
xpathAttributes:
- "name"
- "label"
- "value"
- "resource-id"
- "content-desc"
- "instance"
- "text"
sortByAttribute:
- "depth"
- "list"
- "selected"
findBy: "default"
defineUrl: []
baseUrl: []
appWhiteList: []
urlBlackList: []
urlWhiteList: []
blackList:
- given: []
when: null
then: []
xpath: ".*[0-9]{2}.*"
action: null
actions: []
times: 0
beforeRestart: []
beforeElement:
- given: []
when: null
then: []
xpath: "/*"
action: "Thread.sleep(500)"
actions: []
times: 0
afterElement: []
afterPage: []
afterPageMax: 2
tagLimitMax: 2
tagLimit:
- given: []
when: null
then: []
xpath: "确定"
action: null
actions: []
times: 1000
- given: []
when: null
then: []
xpath: "取消"
action: null
actions: []
times: 1000
- given: []
when: null
then: []
xpath: "share_comment_guide_btn_name"
action: null
actions: []
times: 1000
assertGlobal: []
step2:配置参数
- capability 配置如下
capability:
noReset: "true"
fullReset: "false"
appium: "http://127.0.0.1:4723/wd/hub"
appPackage: com.taobao.taobao
appActivity: com.taobao.tao.welcome.Welcome
automationName: uiautomator2
autoGrantPermissions: true
testcase: 用于启动APP后的基础测试用例
- given: 所有的先决条件,给定一个条件,只有条件成立的时候才完成后面的操作(实际用的较少)
- when: 先决条件成立后的行为,对什么事件做什么事情
- then: 断言集合,事件结束后对结果断言
testcase:
name: "TesterHome AppCrawler"
steps:
- when:
xpath: //*
action: click
- when:
xpath: //*
action: click
then:
- //*[contains(@text, '文案')]
action的动作支持
- "" :只是截图记录
- back:后退
- backApp:回退到当前的App,默认等价于back行为 可定制
- monkey:随机事件
- xxx()执行代码:
- Thread.sleep(1000)
- driver.swipe(0.9,0.8,0.9,0.5)
- click:点击事件
- longTap:长按
- 除以上所有行为外均视为输入行为
selectedList:遍历范围设定,设置让其点击所有可点击的TextView
和ImageView
控件,修改完成如下:
selectedList:
- xpath: //android.widget.ImageView[@clickable='true']
- xpath: //*[@clickable='true' and contains(@class,"Text")]
firstList:优先被点击
lastList:最后执行,设置成点击确定按钮
lastList:
- { xpath: "//*[text()='确定']", action: click }
- backButton:当所有元素都被点击后默认后退控件定位
- blackList:黑名单
- triggerAction: 特定条件出发执行动作的设置
- agLimitMax: 全局设置,同类型的最多点击的次数;这里设置为2次
tagLimitMax: 2
tagLimit: 自定义控件类型的点击次数,这里设置对于ListView
类型的只点击一次;修改完成如下
- { xpath: "//*[contains(@class, 'List')]//*", times: 1 }
maxDepth: 遍历的最大深度
assertGlobal:设置一个全局断言,例如可设置断言在当前App,如果包名不符合,就可能发生了崩溃,便会报错
配置文件:进入淘宝分类页面
---
pluginList: []
saveScreen: true
reportTitle: ""
resultDir: "20210307174024"
waitLoading: 500
waitLaunch: 6000
showCancel: true
maxTime: 10800
maxDepth: 10
capability:
noReset: "true"
fullReset: "false"
appium: "http://127.0.0.1:4723/wd/hub"
appPackage: com.taobao.taobao
appActivity: com.taobao.tao.welcome.Welcome
automationName: uiautomator2
autoGrantPermissions: true
testcase:
name: "进入分类页面"
steps:
- given: []
when: null
then: []
xpath: "//*[@text='分类']"
action: click
actions: []
times: 0
selectedList:
- given: []
when: null
then: []
xpath: "//*[contains(name(), 'Button')]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[contains(name(), 'Text') and @clickable='true' and string-length(@text)<10]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[@clickable='true']/*[contains(name(), 'Text') and string-length(@text)<10]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[contains(name(), 'Image') and @clickable='true']"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[@clickable='true']/*[contains(name(), 'Image')]"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[contains(name(), 'Image') and @name!='']"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[contains(name(), 'Text') and @name!='' and string-length(@label)<10]"
action: null
actions: []
times: 0
firstList: []
lastList:
- given: []
when: null
then: []
xpath: "//*[@selected='true']/..//*"
action: null
actions: []
times: 0
- given: []
when: null
then: []
xpath: "//*[@selected='true']/../..//*"
action: null
actions: []
times: 0
backButton:
- given: []
when: null
then: []
xpath: "Navigate up"
action: null
actions: []
times: 0
triggerActions:
- given: []
when: null
then: []
xpath:
action:
actions: []
times: 0
xpathAttributes:
- "name"
- "label"
- "value"
- "resource-id"
- "content-desc"
- "instance"
- "text"
sortByAttribute:
- "depth"
- "list"
- "selected"
findBy: "default"
defineUrl: []
baseUrl: []
appWhiteList: []
urlBlackList: []
urlWhiteList: []
blackList:
- given: []
when: null
then: []
xpath: ".*[0-9]{2}.*"
action: null
actions: []
times: 0
beforeRestart: []
beforeElement:
- given: []
when: null
then: []
xpath: "/*"
action: "Thread.sleep(500)"
actions: []
times: 0
afterElement: []
afterPage: []
afterPageMax: 2
tagLimitMax: 2
tagLimit:
- given: []
when: null
then: []
xpath: "È·¶¨"
action: null
actions: []
times: 1000
- given: []
when: null
then: []
xpath: "È¡Ïû"
action: null
actions: []
times: 1000
- given: []
when: null
then: []
xpath: "share_comment_guide_btn_name"
action: null
actions: []
times: 1000
assertGlobal: []
step3:配置文件启动:java -jar appcrawler-2.4.0-jar.jar -c demo.yml