AppCrawler 自动遍历工具 2.0 版本发布
自动遍历的价值自动化探索测试, 遍历基本的界面, 了解主要界面的可用性. 比如兼容性, 基本功能
利用遍历获取app的加载时间和性能数据, 需要借助其他的性能数据抓取工具,比如OneApm, NewRelic
利用遍历验证app的内存泄漏以及稳定性等功能, 需要借助LeakCanary和MLeaksFinder
自动化回归测试. UI diff 验证新老版本的功能差异. 并识别细节的问题
抓取接口请求 辅助验证一些模块基本接口, 并辅助分析接口调用流程. 为接口测试做准备
截图
https://testerhome.com/uploads/photo/2017/25cdb6a8-d6cb-4891-b0ff-5ccd7c3005c8.png!large
使用介绍
----------------
AppCrawler 2.0.0
app爬虫, 用于自动遍历测试. 支持Android和iOS, 支持真机和模拟器
帮助文档: http://seveniruby.gitbooks.io/appcrawler
移动测试技术交流: https://testerhome.com
感谢: 晓光 泉龙 杨榕 恒温 mikezhou yaming116
感谢提供商业支持的优秀公司: Keep
--------------------------------
Usage: appcrawler
-a, --app <value> Android或者iOS的文件地址, 可以是网络地址, 赋值给appium的app选项
-c, --conf <value> 配置文件地址
-p, --platform <value> 平台类型android或者ios, 默认会根据app后缀名自动判断
-t, --maxTime <value> 最大运行时间. 单位为秒. 超过此值会退出. 默认最长运行3个小时
-u, --appium <value> appium的url地址
-o, --output <value> 遍历结果的保存目录. 里面会存放遍历生成的截图, 思维导图和日志
--capability k1=v1,k2=v2...
appium capability选项, 这个参数会覆盖-c指定的配置模板参数, 用于在模板配置之上的参数微调
-r, --report <value> 输出html和xml报告
--template <value> 输出代码模板
--master <value> master的diff.yml文件地址
--candidate <value> candidate环境的diff.yml文件
--diff 执行diff对比
-vv, --verbose 是否展示更多debug信息
--help
示例
appcrawler -a xueqiu.apk
appcrawler -a xueqiu.apk --capability noReset=true
appcrawler -c conf/xueqiu.json -p android -o result/
appcrawler -c xueqiu.json --capability udid=[你的udid] -a Snowball.app
appcrawler -c xueqiu.json -a Snowball.app -u 4730
appcrawler -c xueqiu.json -a Snowball.app -u http://127.0.0.1:4730/wd/hub
#启动已经安装过的app
appcrawler --capability appPackage=com.xueqiu.android,appActivity=.welcomeActivity
#从已经结束的结果中重新生成报告
appcrawler --report result/
#新老版本对比
appcrawler --candidate result/ --master pre/ --report ./
#自动生成Page Object代码模板文件
appcrawler --template PageObjectDemo.ssp --output result/
#根据wda的inspector生成测试用例代码
appcrawler --template PageObjectDemo.ssp -u http://localhost:8100重构和不兼容改动
重构了一半多的代码. 提升了性能, 改进测试用例生成的方式. 更快更稳定.
所有的action字段都支持简单的动作和完整的scala编程语句, 样例如下
click 点击
tap 长按
driver.swipe(0.8, 0.8, 0.2, 0.2) 滑动
back 后退
backApp 从其他的app回退到当前app
非以上内容都认为是输入文本
以前的是MiniAppium.xxx, 新版本修改为driver.xxx, 这个driver就是selenium的driver
Appium失败重试
如果appium崩溃了(主要是uiautomator的崩溃), appcrawler会自动重启appium继续测试.
这样需要修改你的遍历配置, 设置为 dontStopAppOnReset: true
androidCapability:
deviceName: "192.168.0.102:5555"
appPackage: "com.gotokeep.keep"
appActivity: ".activity.SplashActivity"
dontStopAppOnReset: true
app: ""
appium: "http://127.0.0.1:4723/wd/hub"
automationName: uiautomator2diff报告改进
进行了更好的分类管理. 根据页面进行分类.
目前可以根据老版本的运行结果来断言新版本的老功能是否符合预期.
分为结果对比和数据对比, 降噪还没实现.
支持macaca
之前硬编码了使用老的uiautomator模式, 这次放开了automationName, 可以支持uiautomator2和macaca了
在automationName处可以指定macaca, 其他配置跟appium一样.
androidCapability:
deviceName: "192.168.0.102:5555"
appPackage: "com.gotokeep.keep"
appActivity: ".activity.SplashActivity"
app: ""
appium: "http://127.0.0.1:4723/wd/hub"
#automationName: uiautomator2
automationName: macaca
reuse: 3全局断言
用来判断app有没有崩溃, 或者点击后有没有特殊的需要注意的控件
asserts:
- given:
- //*
when: []
then:
- //*[@package="com.gotokeep.keep"]
- given:
- //*[@text="发送朋友圈"]
when: []
then:
- //*[@package="com.tencent.mm"]比如设定了断言所有的预期结果里面, 包名都必须是keep, 那么遇到拍照或者发朋友圈, qq登录的地方, 就会提示错误.
https://testerhome.com/uploads/photo/2017/704b636e-6ca3-4c12-a7c3-4cb9d2619537.png!large
https://testerhome.com/uploads/photo/2017/9834f59e-6f65-4613-922f-ad91396be933.png!large
可以通过断言预期结果的基本内容.
yaml风格的自动化测试用例原型
完整的自动化用例支持在2.1.0版本再放出来. 目前的只是demo, 只是用来辅助自动遍历的.
testcase:
name: demo1
steps:
- when:
xpath: //*
action: driver.swipe(0.5, 0.8, 0.5, 0.2)
then: []
- when:
xpath: //*
action: driver.swipe(0.5, 0.2, 0.5, 0.8)
then: []
- when:
xpath: //*
action: tap
then:
- //*
- when:
xpath: //*
action: click
then:
- //*
- //*ChangeLog和下版本的计划
目前为2.0.0版本
2.1.0会未发布的下个版本计划
# 2.1.0
独立的yaml格式的自动化测试用例支持
支持从历史数据中寻找最优点击路径
支持web
支持游戏app遍历
# 2.0.0
支持macaca[完成]
失败重试[完成]
支持简单的测试用例[完成]
架构重新设计[完成]
新老版本对比报告改进[完成]
# 1.9.0
支持遍历断言[完成]
支持历史对比断言[完成]
修正不支持uiautomator2的问题[完成]
支持yaml自动化测试用例[完成]
action支持长按[完成]
重构用例生成方式[完成]完整的配置文件示例
---
logLevel: "TRACE"
reportTitle: "Keep"
saveScreen: true
screenshotTimeout: 20
currentDriver: "android"
showCancel: true
tagLimitMax: 5
tagLimit:
- xpath: //*[../*[@selected='true']]
count: 12
maxTime: 10800
resultDir: ""
capability:
newCommandTimeout: 120
launchTimeout: 120000
platformVersion: ""
platformName: "Android"
autoWebview: "false"
autoLaunch: "true"
noReset: "true"
androidInstallTimeout: 180000
androidCapability:
deviceName: "192.168.0.102:5555"
appPackage: "com.gotokeep.keep"
appActivity: ".activity.SplashActivity"
dontStopAppOnReset: true
app: ""
appium: "http://127.0.0.1:4723/wd/hub"
#automationName: uiautomator2
automationName: uiautomator2
reuse: 3
#nativeWebScreenshot: "true"
defineUrl:
- //*[@selected='true' and contains(name(), 'TextView')]/@text
#- //*/@text
appWhiteList:
- android
- com.shafa.market
baseUrl:
- ".*MainActivity"
- ".*SNBHomeView.*"
maxDepth: 20
headFirst: true
enterWebView: true
urlBlackList:
- .*OutdoorSummaryMap.*
- .*PersonalPage.*
- .*Training.*
- .*FriendRank.*
- .*\\.base\\.Container.*
#urlWhiteList:
#- ".*Main.*"
backButton:
- //*
#defaultBackAction:
#- import sys.process._;
#- Thread.sleep(5000)
#- val name=Seq("adb", "shell", "dumpsys window windows | grep mCurrentFocus").!!.split(" ")(4).split("/")(0)
#- println(s"kill package ${name}")
#- Seq("adb", "shell", s"am force-stop ${name}").!!
#firstList:
#- //*
selectedList:
#android非空标签
- //*[@clickable='true']
- //*[@clickable='true']//*
#通用的button和image
- //*[@clickable='true']//*
- //*[@clickable='true']//*
#todo:如果多个规则都包含相同控件, 如何排序
#处于选中状态的同级控件最后点击
lastList:
- //*[../*[@selected='true']]
- //*[../../*/*[@selected='true']]
- //*[../../*/*[@selected='true'] and contains(@resource-id, 'tab_')]
- //*
- //*[@resource-id='com.gotokeep.keep:id/layout_bottom']
blackList:
- ".*\\..*"
- ".*{2,}.*"
- //*//*
- //*
- //*
- //*
- //*
triggerActions:
- xpath: //*//*[@text="确定"]
- xpath: //*//*[@text="不发了"]
- xpath: //*[@text="拒绝"]
- xpath: //*[@text="放弃"]
- xpath: //*[@text="结束训练"]
- xpath: //*//*
- xpath: //*//*
action: yoga
times: 1
asserts:
- given:
- //*
then:
- //*[@package="com.gotokeep.keep"]
- given:
- //*[@text="胸部"]
then:
- //*
testcase:
name: demo1
steps:
- when:
xpath: //*
action: driver.swipe(0.5, 0.8, 0.5, 0.2)
then: []
- when:
xpath: //*
action: driver.swipe(0.5, 0.2, 0.5, 0.8)
then: []
- when:
xpath: //*
action: tap
then:
- //*
- when:
xpath: //*
action: click
then:
- //*
- //*
#所有view的叶子节点 一般表示游戏
#- action: monkey
#xpath: //android.view.View") ]
#times: 20
#startupActions:
#- println(driver)
#beforeElementAction:
#- xpath: //*[@resource-id="com.shafa.market:id/nav"]//android.widget.TextView
#action: MiniAppium.event(21)
#- Thread.sleep(3000)
#- println(driver.getPageSource())
#afterElementAction:
#- println(driver)
#afterUrlFinished:
#- monkey()
:lol 赞一个!啥时候用Java或Python重写:lol 人生苦短,请用python,期望来个python版本 咨询个问题,如果是手机已经有的apk,用那个指令来启动呢,说明,这个apk无法卸载,也无法直接安装新的应用 这个不错,我现在公司,也在写遍历测试,算完成50%,一半一半。你这个我使用下。看了文档,就是用例格式的yaml,就是没有类似jason格式解析,比较不好判断哪里出错吧 乐哈哈yoyo 发表于 2017-6-26 14:49
咨询个问题,如果是手机已经有的apk,用那个指令来启动呢,说明,这个apk无法卸载,也无法直接安装新的应用
你估计不懂appium吧, 你可以看看他的文档, 简单来说, capability里面的app参数不写即可.
页:
[1]