https://testerhome.com/topics/5718
结贴
工具在筹备 1.4.0 版本的发布. 所以暂不回答大家各种重复的问题了. 我创建了一个 qq 交流群: 177933995 可自行加入
3 月份高鹏 徐世钊 mingway 在阿里巴巴举办了第四届 TesterHome 线下沙龙
我在沙龙中分享了 AppCrawler 自动遍历工具的前世今生和一些 feature.
当时因为在完善一些细节. 所以没有放出来试用版本. 今天算是给大家补上吧.
增加了一个实验性的自动化测试框架. 放出来也是想让大家当小白鼠
增加了自动化测试的支持. 可以在自动化中进入自动遍历.
增加了 Log 插件. 支持读取 Android 的 Logcat 和 iOS 的 syslog 数据.
增加了 TagLimit 插件. 用于自动识别类似的控件减少遍历, 加快速度.
使用了标准的 log4j 风格的 Log 输出
增加了启动的默认划屏操作
我把工具打包成了 jar 包.
百度网盘: http://pan.baidu.com/s/1pLcjBkB
新浪微盘: http://vdisk.weibo.com/s/aii55uMrHR9DZ
开源时间还不确定. 心急的同学可以自行反编译. :)
首先安装 appium 并启动
#安装appium
npm install -g appium
#启动appium Android测试默认连接4730端口的appium. iOS使用的是默认的4723
#如果是Android
appium -p 4730
#如果是iOS测试
appium
以雪球的 app 为例. 雪球是著名的炒股和购买基金的产品, 里面的细分功能会比较多. 你可以借助它了解下自动遍历的大概过程.
首先下载雪球的 app http://xqfile.imedao.com/android-release/xueqiu_761_04122000.apk
因为雪球 app 的默认 LauncherActivity 有点特殊. Appium 识别不出来. 所以得手工加上一个 capability 的参数.
如果是其他的 app, 就不需要了. 执行命令如下
java -jar appcrawler-1.2.1.jar -a xueqiu.apk -o demo/ --capability appActivity=.view.WelcomeActivityAlias
当然也有个一键下载并执行的方法, 只是这样下载 app 会比较慢. 只有内网做持续集成的时候才适合.
java -jar appcrawler-1.2.1.jar -a http://xqfile.imedao.com/android-release/xueqiu_761_04122000.apk -o demo/ --capability appActivity=.view.WelcomeActivityAlias
然后就可以出去喝茶了. 回来之后你就可以在 demo 目录下看结果了. 目前的速度是 Android 一小时一千张. iOS 一小时三百张截图的样子.
查看完整帮助
java -jar target/scala-2.11/appcrawler-1.2.1.jar
AppCrawler 1.2.0
app爬虫, 用于自动遍历测试. 支持Android和iOS, 支持真机和模拟器
灵感来源: 晓光 泉龙 杨榕 雪球测试团队出品
移动测试技术交流 https://testerhome.com
Usage: appcrawler [sbt] [options] <args>...
-a <value> | --app <value>
Android或者iOS的文件地址, 可以是网络地址, 赋值给appium的app选项
-c <value> | --conf <value>
配置文件地址
-p <value> | --platform <value>
平台类型android或者ios
-t <value> | --maxTime <value>
最大运行时间. 单位为秒. 超过此值会退出. 默认最长运行3个小时
-u <value> | --appium <value>
appium的url地址
-o <value> | --output <value>
遍历结果的保存目录. 里面会存放遍历生成的截图, 思维导图和日志
--capability k1=v1,k2=v2...
appium capability选项, 这个参数会覆盖-c指定的配置模板参数, 用于在模板配置之上的参数微调
-v | --verbose
是否展示更多debug信息
--help
示例
appcrawler -a xueqiu.apk
appcrawler -a xueqiu.apk --capability noReset=true
appcrawler -c conf/xueqiu.json
appcrawler -c xueqiu.json -p ios --capability udid=[你的udid] -a Snowball.app
appcrawler -c xueqiu.json -p ios -a Snowball.app -u http://127.0.0.1:4730/wd/hub
Command: sbt [<sbt params>...]
sbt是一个调用sbt命令运行测试的开关. 可以传递sbt的参数
<sbt params>...
sbt的参数列表
一份未完成的文档
百度网盘: http://pan.baidu.com/s/1c8yjgi
新浪微盘: http://vdisk.weibo.com/s/aii55uMrHRamh
不是重复造轮子. 是 scalatest 自带的一个 selenium 的封装. 我之前在社区发过
我新增了三个关键词来简化测试步骤
see 定位方法
tree 元素访问方法
send 发送文字
click on 点击
唯一的元素定位方式.
see 是引用了<阿凡达>电影里面一句台词"I See You". 它的作用是当你看到一个控件, 你应该可以根据看见的东西就可以定位它, 无须借助其他工具或者使用 findElementByXXX 之类的函数.
比如有个 Button, 名字是"登录", 它的 id 是 account, 定位它可以通过如下多种方式的任何一种
如果当前界面中存在了有歧义的控件, 比如其他一个名字为"登录"的输入框. 那么上述定位方法中定位中两个控件的定位方法会失效, 你需要自己调整即可.
关于元素定位你只需要用 see 这个方法即可.
打印当前界面布局结构. 是个格式化的 xml 内容.
如果传入一个参数 则会打印符合你给定关键词或者 xpath 定位的元素列表
这个关键词是为了让你摆脱各类的元素定位工具, 比如 appium inspector, uiautomator 之类的工具.
# 这是对应的控件的所有属性
Map(x -> 0, name -> 注册, path -> /0/0/4, visible -> true, y -> 202, tag -> UIAStaticText, enabled -> true, label -> 注册, dom -> , height -> 44, UIAStaticText -> null, xpath -> //UIAApplication[@name="雪球" and @path="/0"]/UIAWindow[@path="/0/0"]/UIAStaticText[@name="注册" and @path="/0/0/4"], valid -> true, hint -> , loc -> //UIAApplication[@name="雪球" and @path="/0"]/UIAWindow[@path="/0/0"]/UIAStaticText[@name="注册" and @path="/0/0/4"], width -> 187.5, value -> 注册)
用于获取当前dom树里面满足条件的第一个控件的属性. 比如我想获取某个TextView的相关属性. 可用
- tree("action_bar_title")("text") 文本
- tree("action_bar_title")("tag") 类型
- tree("action_bar_title")("selected") 是否选中
### demo例子
验证iOS上的设备的兼容性. 只是一个粗糙的小用例. 不是正规的应用. 正规的应用需要把设备数据和用例拆分开. 我这是为了方便简写了一个可运行的用例.
```scala
class TestAppiumDSL extends AppiumDSL {
import org.scalatest.prop.TableDrivenPropertyChecks._
val table = Table(
("iPhone 4s", "9.1"),
("iPhone 5", "8.1"),
("iPhone 5", "9.2"),
("iPhone 5s", "9.1"),
("iPhone 6", "8.1"),
("iPhone 6", "9.2"),
("iPhone 6 Plus", "9.1"),
("iPhone 6s", "9.1"),
("iPhone 6s", "9.2"),
("iPad Air", "9.1"),
("iPad Air 2", "9.1"),
("iPad Pro", "9.1"),
("iPad Retina", "8.1"),
("iPad Retina", "8.2")
)
forAll(table) { (device: String, version: String) => {
test(s"兼容性测试-${device}-${version}_登录验证iphone", Tag("7.7"), Tag("iOS"), Tag("兼容性测试")) {
iOS(true)
config("deviceName", device)
config("platformVersion", version)
setCaptureDir("/Users/seveniruby/temp/crawl4")
appium()
captureTo(s"${device}-${version}_init.png")
click on see("手机号")
send("1560053xxxx")
click on see("//UIASecureTextField")
send("password")
captureTo(s"${device}-${version}_login.png")
click on see("登 录")
captureTo(s"${device}-${version}_main.png")
if(device.matches(".*iPad.*")){
click on see("//UIAButton[@path=\"/0/0/0/5\"]")
}else {
click on see("//UIAButton[@path=\"/0/0/3/5\"]")
}
tree("seveniruby")("name") should be equals "seveniruby"
captureTo(s"${device}-${version}_profile.png")
}
}
}
{
"pluginList" : [
"com.xueqiu.qa.appcrawler.plugin.TagLimitPlugin"
],
"saveScreen" : true,
"currentDriver" : "android",
"maxTime" : 10800,
"resultDir" : "",
"capability" : {
"deviceName" : "",
"platformVersion" : "",
"platformName" : "",
"launchTimeout": 120000,
"newCommandTimeout": 120,
"autoWebview" : "false",
"autoLaunch" : "true",
"noReset" : "false"
},
"androidCapability" : {
"deviceName" : "demo",
"appPackage" : "com.xueqiu.android",
"appActivity" : ".view.WelcomeActivityAlias",
"app" : ""
},
"iosCapability" : {
"deviceName" : "iPhone 6",
"bundleId" : "",
"platformVersion" : "9.1",
"autoAcceptAlerts" : "true",
"app" : ""
},
"defineUrl" : [
"//*[@resource-id='com.xueqiu.android:id/indicator']//*[@selected='true']",
"//*[@resource-id='com.xueqiu.android:id/tab_name' and @selected='true']",
"//UIANavigationBar[1]",
"//*[contains(@name, '_title')]",
"//*[contains(@resource-id, 'action_bar_title')]"
],
"baseUrl" : [ ".*MainActivity", ".*SNBHomeView.*" ],
"maxDepth" : 20,
"blackUrlList" : [ ".*球友.*", ".*png.*", ".*Talk.*", ".*Chat.*", ".*Safari.*", "WriteStatus.*", "Browser.*", "UserProfile.*", ".*消息.*", "MyselfUser", ".*消息.*", ".*MyselfUser.*", ".*股市直播.*", ".*UserVC.*", ".*正文页.*", "SNBTradeSegment" ],
"backButton" : [
"//*[@resource-id='action_back']",
"//*[@resource-id='android:id/up']",
"//*[@resource-id='android:id/home']",
"//*[@resource-id='android:id/action_bar_title']",
"//*[@name='nav_icon_back']",
"//*[@name='Back']",
"//*[@name='返回']",
"//UIAButton[@name='取消']",
"//UIAButton[@label='返回']",
"//UIAButton[@name='关闭']",
"//UIAButton[@name='首页']" ],
"firstList" : [
"//UIACollectionView//*",
"//UIAPopover//*",
"//UIAWindow[3]//*[not(ancestor-or-self::UIAStatusBar)]",
"//UIAWindow[2]//*[not(ancestor-or-self::UIAStatusBar)]",
"//android.widget.ListView//android.widget.TextView",
"//android.widget.ListView//android.widget.Button",
"//UIAWindow[1]//UIATableView//UIATableCell[@name!='']",
"//UIAWindow[1]//UIAStaticText//UIATableCell[@dom!='' and @name!='']"
],
"selectedList" : [
"//*[@resource-id!='' and not(contains(name(), 'Layout'))]",
"//*[@content-desc!='' and not(contains(name(), 'Layout'))]",
"//android.widget.TextView[@clickable='true']",
"//android.widget.ImageView[@clickable='true']",
"//*[contains(name(), 'Text')]",
"//*[contains(name(), 'Image')]",
"//*[contains(name(), 'Button')]",
"//*[not(ancestor-or-self::UIAWebView)]"
],
"lastList" : [
"//*[contains(@resource-id,'group_header_view')]//android.widget.TextView",
"//*[contains(@resource-id,'indicator')]//android.widget.TextView"
],
"blackList" : [
"//*[name()='UIATextField']",
"//*[contains(name(), 'EditText')]",
"//UIAStatusBar//*",
".*Safari", ".*电话.*", ".*Safari.*", "发布", "action_bar_title", ".*浏览器.*", "message", ".*home", "首页", "消息", "弹幕", "发射", "Photos", "地址", "网址", "发送", "拉黑", "举报", "camera", "Camera", "点评", "nav_icon_home", "评论", "回复", "咨询", "分享.*", "转发.*", "comments", "comment", "stock_item_.*", ".*[0-9]{2}.*", "弹幕", "发送", "保存", "确定", "up", "user_profile_icon", "selectAll", "cut", "copy", "send", "买[0-9]*", "卖[0-9]*", "聊天.*", "拍照.*", "发表.*", "回复.*", "加入.*", "赞助.*", "微博.*", "球友.*", ".*开户.*" ],
"elementActions" : [ {
"action" : "click",
"idOrName" : "//*[@resource-id='com.xueqiu.android:id/button_login']",
"times" : 1
}, {
"action" : "xxxxx",
"idOrName" : "//*[@resource-id='com.xueqiu.android:id/login_account']",
"times" : 1
},{
"action" : "xxxxxx",
"idOrName" : "//*[@resource-id='com.xueqiu.android:id/login_password']",
"times" : 1
}, {
"action" : "click",
"idOrName" : "button_next",
"times" : 1
},{
"action" : "xxxxxx",
"idOrName" : "//UIAStaticText[contains(@name, '登录')]",
"times" : 1
},{
"action" : "xxxxxx",
"idOrName" : "//UIATextField[contains(@value, '手机')]",
"times" : 1
}, {
"action" : "xxxx",
"idOrName" : "//UIASecureTextField",
"times" : 1
},{
"action" : "click",
"idOrName" : "//UIAButton[contains(@name, '登 录')]",
"times" : 1
}, {
"action" : "click",
"idOrName" : ".*立即登录",
"times" : 2
}, {
"action" : "click",
"idOrName" : "//*[@name='登 录']",
"times" : 2
}, {
"action" : "click",
"idOrName" : "//*[@name='登录']",
"times" : 2
}, {
"action" : "scroll left",
"idOrName" : "专题",
"times" : 1
},{
"action" : "click",
"idOrName" : "点此.*",
"times" : 0
}, {
"action" : "click",
"idOrName" : "不保存",
"times" : 0
}, {
"action" : "click",
"idOrName" : "确定",
"times" : 0
}, {
"action" : "click",
"idOrName" : "关闭",
"times" : 0
}, {
"action" : "click",
"idOrName" : "取消",
"times" : 0
}, {
"action" : "click",
"idOrName" : "稍后再说",
"times" : 0
}, {
"action" : "click",
"idOrName" : "Cancel",
"times" : 0
}, {
"action" : "click",
"idOrName" : "这里可以.*",
"times" : 0
}, {
"action" : "click",
"idOrName" : ".*搬到这里.*",
"times" : 0
}, {
"action" : "click",
"idOrName" : "我要退出",
"times" : 0
}, {
"action" : "click",
"idOrName" : "tip_click_position",
"times" : 0
}, {
"action" : "click",
"idOrName" : "common guide icon ok",
"times" : 0
}, {
"action" : "click",
"idOrName" : "icon quotationinformation day",
"times" : 1
}, {
"action" : "click",
"idOrName" : "icon stock close",
"times" : 0
}, {
"action" : "click",
"idOrName" : "隐藏键盘",
"times" : 0
}],
"startupActions" : [ ]
}
很多人都在反馈相同的问题, 我工作很忙, 所以就结贴了.
列举下大家反馈的问题. 然后等新版本吧.
各位看官如果阅读的赏心悦目的话, 记得点击帖子下方的"打赏"按钮给打个赏.
沙发,利器啊
厉害,这个相当实用
还在审核中,等通过了试用一下
#2 楼 @snowmaster 你试用了?
相当叼!
还在审核中。。。
#5 楼 @lihuazhang 上传到新浪微盘了. 新浪貌似要审核. 我一会也传百度网盘一份.
#4 楼 @lihuazhang 下载地址的微盘显示还在审核,现在还下载不了
#8 楼 @seveniruby 辛苦啊,还是百度云快一些
终于等到了。。。。努力折腾一下 -___.-
输入命令,进行试用的过程中,报错了,请教下,是什么原因尼?
#12 楼 @mistyrain 你是不是没启动 appium
#13 楼 @seveniruby 我是通过界面进行启动的,看日志好像是启动成功了。
#14 楼 @mistyrain android 测试默认连接的是 4730 端口. 你把 appium 的端口调整到 4730 吧
#15 楼 @seveniruby 嗯,谢谢回复,我刚才修改了一下端口,好像还是报同样的错误。
#15 楼 @seveniruby 终于搞定了,可以运行了。主要遇到两个问题,一个是 server address, 是需要配置成 127.0.0.1,发现网上有资料说要配置成电脑 ip,但是完全不行。另外还有一个问题,需要将应用的安装包,放到 appium 的 resource 目录下,否则会提示失败。
思寒,我这边有另外一个问题,就是这个遍历工具,每次都需要卸载重装,但是我目前的需求是,因为应用需要手动准备一些数据,这样能够遍历的更加充分一些,所以有没有方法直接进行遍历,不用每次安装卸载尼?
#17 楼 @mistyrain 本来就支持. 你不写-a 参数就可以了. 这个不是我工具的 feature, 是 appium 本来就支持. 细节控制可以用 capability 参数. 这个跟 appium 的 capability 是一致的.
appium 的地址那个本地可以, 远程也是可以的. 取决于你启动 appium 的时候填写的 ip. 填 127.0.0.1 就是本地才能访问, 填写 0.0.0.0 则电脑就可以访问.
目前的遍历规则是最简单的.企业需要自己定制自己的配置文件才能遍历的更彻底.
棒棒哒
好东西,PS:建议可以封装 sikuli 的方法对截图下来的进行模式匹配,这样兼容性测试就是一套完整的了
赞,已用上
@seveniruby 求解答,为什么提示我找不到包?
win10 和 ubuntu14.04 下不支持吗?
win10 下可以了,原来 -o 参数后边接的 apk 路径 必须是绝对路径,我说楼主 你也不说明白。。。。。
跑了一下 一个字:NiuB
ps:如果 app 中某些场景会跳转系统设置页面,是不是会懵逼(把设置的功能都跑一遍)
攒,初步用了一下,貌似还可以
已成功跑起来,记得加
-o demo/ --capability appActivity=.view.WelcomeActivityAlias
试用了一下,对 native 的支持应该没问题,目前看来对 webview 的支持会差一些,可能需要通过修改超时时间来达到目的
#17 楼 @mistyrain 安装包的问题,直接写安装包的绝对路径就 ok
-c | --conf
配置文件地址
能不能请问一下,这个配置文件如何编写及使用
error: Failed to start an Appium session, err was: Error: Bad app: null. App
扫描后 freemind.mm 用 freemind 打开报错了
Error while parsing file:freemind.main.XMLParseException: XML Parse Exception during parsing of a map element at line 2: Expected: =
#28 楼 @qi_ling2005 还是会报错的,error: Failed to start an Appium session, err was: Error: Bad app: null. App paths need to be absolute, or relative to the appium server install dir, or a URL to compressed file, or a special app name. cause: Error: You passed in an app package as the 'app' capability, but didn't include appActivity. We need to know that too in order to start your app
#32 楼 @xiaoyi614 jar 和 apk 放到一个目录下就可以了,我这没问题
#32 楼 @xiaoyi614 @harsayer 这个是 appium 的限制. 我只是传参数给他. 不过考虑到大家都遇到这个坑了. 我就刚做了封装. 明天发出来.
#33 楼 @seveniruby 感谢回复! appium 1.4.13.1 版本的能跑起来,效果很嗨皮,1.4.16.1 失败了!
#34 楼 @xiaoyi614 我是在 1.5.1 上做的测试. 1.4.16 是有点小毛病. appium 有些小 bug
@seveniruby 我看了下扫描结果文件夹下的图片,仔细对比了下 app 应用,发现只是遍历 native 原生 android 框架吗?
然后对首页的焦点展示图 向右滑动 访问了第二个焦点的链接,并向下滑动浏览然后回退再浏览。
我想知道的是,怎么自己控制这些遍历业务流程? 哦 还有扫描出来的 freemind.mm 文件打开是报错的 用的是最新的 FreeMind-Windows-Installer-1.0.0-min.1185392965.exe 打开的。xmind 想打开也保错了。
反编译不了,这是为什么呢?其他 jar 可以正常反编译。
#24 楼 @phicomm123 如果跳转到 web 浏览器,还会把浏览器跑一遍
@seveniruby 我试跑了一段时间,发现 demo 文件夹下有好多.dom 文件,还有好多空的 jpg 文件, 不知道是什么原因?
系统是 mac, appium 是 1.4.0
#39 楼 @qi_ling2005 这个自己控制就行了. 默认会跑浏览器. 我自己用的时候会有自己的配置文件过滤了浏览器了.
#40 楼 @qi_ling2005 dom 文件是屏幕上所有的控件的文本信息. 是个 xml. 是辅助分析的文件. 等价于 getPageSource 的结果.
@seveniruby 非常期待啊!
brew install -g appium 应该是 npm ba
看起来很牛逼的样子,抽空使用一下
—— 来自 TesterHome 官方 安卓客户端
#47 楼 @lihuazhang 我修改下
#48 楼 @seveniruby 楼主 新包好了嘛,期待中......
#18 楼 @seveniruby 哪个步骤不对么?
elementActions:
{
"action" : "click",
"idOrName" : "我的",
"times" : 3
}
这个 action 是否支持滑动操作?
#52 楼 @michael_wang 暂不支持. 下个版本加上.
#54 楼 @seveniruby 我用你的那个链接 下载的雪球 我试试其他 apk 吧
#54 楼 @seveniruby 我把 -a 参数拿掉了, capability 加了包名可以了
#53 楼 @seveniruby 请问 apk 安装启动后出现闪退是什么问题?
如果是商城类型的 app,想让这个工具把每一篇商品详情内的所有控件都进行点击一遍,而不是点过一篇后,其他的就认为都是点过了,通过 conf 中的配置文件可以实现吗?
#58 楼 @michael_wang 可以, 这个需要重定义 url. 在 url 中加入详情页的标题就可以了. 这个目前没有放出来配置说明 其实就是定义那个 defineUrl 配置
#18 楼 @seveniruby 思寒,有没有一个详细的遍历配置的编写说明尼?现在不太清楚要怎么来编写~
#60 楼 @mistyrain 下个版本我增加一个自动生成默认的配置文件模板
@seveniruby 工具已经跑起来了,想到一个问题请教,就是已经安装在手机上的应用怎么跑,结果发现好像必须得有 app 的包啊,还是说我的配置错了??
#61 楼 @seveniruby 嗯,期待~下个版本预计什么时候更新尼?
@seveniruby 查看 help 提示是 --capability k1=v1,k2=v2... 然后我就用了上面截图中的命令 K1 和 K2 我是用的空格报错 然后得到你的肯定回复后我就多试了几下 把 K1 和 K2 中间价格逗号就 OK 了
你好,问下在测试 iOS 应用时,安装应用后第一次启动系统都会弹出类似 “XX 想给您发送推送通知"弹窗,然后就无法遍历了,只能手动点允许或取消才能继续。这个有办法解决么?
#64 楼 @mistyrain 已经交给一些人内测了.
#67 楼 @seveniruby 如图这个提示会一直存在,导致无法正常遍历,然后显示 ScriptAgent 崩溃了。
#70 楼 @seveniruby 意思在配置文件中配置规则点击是没用的?和 appium 版本有关?我的用的 iphone6 9.0+Mac OS 10.11+appium 1.4.13,能问你的环境不
没找到 1.5.2 的 mac 版。。。只有源码
@seveniruby ,我的也是 1.4.16,运行有问题,能给个 1.5.1 的版本吗?
?yun
#70 楼 @seveniruby 你好,请问有没有参数可以设置不输出结果?
什么时候开源,最近有个任务正好用到,再不开源只能自己做了
运行没多久截图的时候就报错了:
我是小白,这个怎么用
试用下
@seveniruby
请教下,为什么我用-c 指定 json 配置文件后总是报这个错
Exception in thread "main" java.nio.charset.UnmappableCharacterException: Input
length = 2
at java.nio.charset.CoderResult.throwException(CoderResult.java:278)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:338)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.read1(BufferedReader.java:203)
at java.io.BufferedReader.read(BufferedReader.java:279)
at java.io.Reader.read(Reader.java:140)
at scala.io.BufferedSource.mkString(BufferedSource.scala:96)
at CrawlerConf.load(CrawlerConf.scala:148)
at AppCrawler$.main(AppCrawler.scala:117)
at AppCrawler.main(AppCrawler.scala)
#81 楼 @finelucky 遇到过类似的问题,试试将配置文件中的中文转成 Unicode,例如: "action" : "测试地址" 改成 "action" : "\u6d4b\u8bd5\u5730\u5740"
我也是用的中文, 没问题. 你们是不是都是 windows. windows 保存的时候有时候格式不标准. 可能会引发问题. 估计需要框架做个兼容才行.
{
"action" : "click",
"idOrName" : "点此.*",
"times" : 0
}, {
"action" : "click",
"idOrName" : "不保存",
"times" : 0
},
#82 楼 @fwcco2605 Thanks,确实转换成 Unicode 就可以了
#83 楼 @seveniruby 请教下,当被测程序出现 Crash 后的处理机制是什么样的呢?我现在在 Genymotion 上出现 Crash 后,从 appcrawler.log 中看到程序就在桌面上继续操作了。另外,如果出现 “[AndroidCrawler.doAppiumAction] find error” 是否就表示被测程序出现异常?
#86 楼 @finelucky 会自动判断当期界面是否是 Launcher, 如果是就认为是退出了. 遇到什么条件就退出这个我没做配置化. 的确使用的时候会是一个问题的. 有些机器的桌面名字不是 Launcher, 就会导致崩溃了仍然会跑. 这个我在下个版本里面修复下吧.
#87 楼 @seveniruby 登录时的手势密码,如何处理
#87 楼 @seveniruby 还有个问题要请教下,json 配置中的 deviceName 事不是就定义了连接哪个设备进行测试?但是好像没起作用啊
json 配置:
"capability" : {
"deviceName" : "192.168.56.101:5555",
"platformVersion" : "",
"platformName" : "",
"autoWebview" : "false",
"autoLaunch" : "true",
"noReset" : "false"
},
appium 中:
[debug] [ADB] Running D:\software\adt-bundle-windows-x86_64-20140702\sdk\platfor
m-tools\adb.exe with args: ["-P",5037,"-s","Baytrail59DCE59F","shell","ps","uiau
tomator"]
[ADB] No uiautomator process found to kill, continuing...
#89 楼 @finelucky 这个参数是传递给 appium 的. appium 那边在 android 上不起作用.
#90 楼 @seveniruby 关于窗口迁移,用 activity 不行,很多 tab 窗口内容不一样,同属一个 activity
用 md5 也不靠谱,页面有细微的变化就变了,窗口迁移处理和跳窗处理你有好的解决方案吗?
ios 的跳窗处理更蛋疼了,感觉 defineUrl 还是指标不治本,还是我理解的有问题。。。
#91 楼 @seveniruby 刚才试验了下任务栈黑名单机制和任务栈自动重置的策略,现在对窗口迁移和跳窗的判断依赖小了很多,稳定性显著提高了
@seveniruby 现在代码在 github?private?
#96 楼 @chenDoInG 还未到开源状态, 会先开放给一些技术高手. private
#95 楼 @seveniruby 公司邮箱不能访问外网,个人邮箱:quqing0930@126.com
#92 楼 @seveniruby 我又想到一个方法,判断窗口是否迁移,待会实验一把
把操作前、操作后的两个窗口文件按顺序解析出可执行节点,每个节点用 xpath 的绝对路径做唯一标识,保存在两个集合,然后进行差异性比较。举个例子:如果差异率小于 10%(按实际情况自己配置),则认为是 同一窗口下的任务,去重后合并成一个新的任务栈
#99 楼 @seveniruby 看样子,你也踩了不少坑
#100 楼 @seveniruby 我现在跑的挺稳定的,唯一的遗憾是这个问题没彻底解决,导致部分窗口的任务可能重复跑影响效率
#103 楼 @seveniruby 任务催的紧,两星期没睡好觉,马不停蹄的摸索,踩坑,填坑,今天算是稳定版交差了,接下来是核心算法的优化了,你的文章给了我启发,少走了弯路
额。。我没有做过移动端的测试。所以我问个无知的问题。自动遍历解决了什么问题?检测 crash?
#92 楼 @seveniruby 参考了几款 app,defineUrl 可能不能解决一些特殊情况,例如:有的窗口有 title,有的窗口没有 title,有的窗口 title、tab 完全一样,选择不同 tab 的内容不一样,有的 app 窗口内控件的命名规则太随意,很难用一个 defineUrl 适配所有窗口,可能还有许多未知的情况。
今天总结后又想到一个方法,以 android 为例:按顺序解析 xml 所有节点,但只取除坐标之外的属性和 text 拼接成字符串,默认取前面 30 个节点的内容(用户通过配置自定义)生成 md5,觉得这样的通用性和辨识率会大大提高
滑动操作 有没有什么好的思路?如何跟点击完美结合?
试用了下,app 一开始就得登录的情况,怎么解决。
#109 楼 @shijin880921 看文档, 里面解决办法. 使用触发器规则
请问一下可以控制不走 UIWebView 么?进去 webview 有很多网页元素。
#111 楼 @guaixiaomei 通过文档里面提到的 blackUrlLIst 去控制
freemind 打不开,报错:Error while parsing file:freemind.main.XMLParseException: XML Parse Exception during parsing of a map element at line 2: Expected: =
@seveniruby 目前测试 iOS app 过程中遇到一个问题,遍历过程中碰到用浏览器打开等跳转到其它 app 的问题,点击后跳转到浏览器 app 了,有什么方法自动回退到原来的 app 么?
@seveniruby 运行时遇到无法启动 Activity 的问题(见下图),是否是需要加参数去控制
请问,app 需要登录用户名和密码输入的,如何操作才可以记录录制呢?
安装应用后 iOS 会弹出 是否允许通知推送的 系统对话框,这个 appium 需要配置那些参数呢?waitForAppScript : “true;”,等等我试了好多,都不行。有碰到的么?
你好问一下。跟踪日志里有 INFO [TagLimitPlugin.beforeElementAction] xxx need skip。就不去点击了。这个是根据什么决定的?
#118 楼 @guaixiaomei TagLimit 是个插件. 默认相同类型的控件只点击一定的次数. 如果超额了就会跳过不再点击类似的空间, 是为了防范那些永远也刷不完的列表.比如微博这种. 目前我写死了次数. 没法从外面配置. 如果不是测试性能, 一般默认就可以了. 你可以在配置文件中去掉这个 TagLimit 插件来禁用这个功能
试用了一下,测试对象是 IOS app 有以下几个问题:
使用命令:
java -jar appcrawler-1.2.1.jar -p ios --capability uuid= -a xxx.app
1、如果启动 appium 的时候直接使用文章里介绍的 appium,总是会提示 Installing xxx.app failed
后面我是直接使用:appium -U --app ,然后就好了
2、开始工作后,由于我们的应用有欢迎页,然后是向左滑动的,这里自动化遍历会卡在一直向右滑动
3、后续没有欢迎页后,遍历时重复访问到某个页面后由于超过次数就退出了。。。
#120 楼 @lynnfang0917 第一个问题我觉得是你搞错了. 是 udid 不是 uuid. 你把 key 搞错了.
第二个问题可以通过配置文件来设定是左划还是右划多少次.
第三个问题是默认只访问简单的文本和图片元素. 如果你们的元素特殊, 需要自己修改配置文件改进下.
#119 楼 @seveniruby 原来是这样啊。那需要在配置文件怎么去除呢?我看了你的文档,好像提到插件开发的地方是空白。不太懂怎去掉,谢谢
@seveniruby 这个自动遍历现在还不在 github 上?
#123 楼 @lihuazhang 中国移动测试大会的时候放上去, 现在还是 gitlab 上, 只是分享给了少数人.
#122 楼 @guaixiaomei pdf 版本的文档里面有提到吧. plugins 里面去掉即可
@seveniruby 请教大神,最近在学习 Appium 看到您自动化遍历的工具,之前自己也思考过实现遍历功能,想了解下实现的思路是怎样的~还望赐教!
#127 楼 @lihuazhang 是啊. 到时候会有黑客圈的人用这个. 我得赶紧放个新版本出来. 开源等大会的时候再宣布
请问,这是什么原因?
#129 楼 @cy_suncheng 这个版本的 bug, app 里面有特殊字符会导致拼装 xml 失败. 下个版本解决
好东西,学习中
楼主,想问下这个遍历过程中有没有做某些屏蔽,比如遍历图库 app,测试过程中可能会点到 “全选”,然后 “删除”,这样造成被测资源为空的情况,遍历的有效性很低了
想问楼主这种情况有做兼容吗?
谢谢!
#134 楼 @CrystalChen1017 支持, 自己看下文档吧.
之前看了些文章,1、说自动化遍历可以通过 xml 属性中基于 clickable 来实现~不知道 appCrawler 这个实现原理是?
2、如果遍历过程中出现 app 崩溃,闪退,这 appCrawler 会重启在执行嘛?
appCrawler 如果深度遍历,提个建议,能不能形成二叉树遍历模型图,这样更容易看出来遍历的过程和进度。。。。
跑了一个小时报错了,观察当前页面还可以继续下划的。请问这是什么情况呢?
求 share 配置文件,conf.json 那个文件。。。
freemind 打不开,报错:Error while parsing file:freemind.main.XMLParseException: XML Parse Exception during parsing of a map element at line 2: Expected: =
info: [debug] Responding to client with error: {"status":13,"value":{"message":"An unknown server-side error occurred while processing the command.","origValue":"Failed to Dump Window Hierarchy"}
sionId":"ee60dc85-73ba-489f-bfdb-c8c1c3ef18f0"}
info: <-- GET /wd/hub/session/ee60dc85-73ba-489f-bfdb-c8c1c3ef18f0/source 500 24.455 ms - 200
info: [debug] [UIAUTOMATOR STDOUT] junit.framework.TestResult.runProtected(TestResult.java:133)
info: [debug] [UIAUTOMATOR STDOUT] at junit.framework.TestResult.run(TestResult.java:118)
info: [debug] [UIAUTOMATOR STDOUT] at junit.framework.TestCase.run(TestCase.java:124)
info: [debug] [UIAUTOMATOR STDOUT] at com.android.uiautomator.testrunner.UiAutomatorTestRunner.start(UiAutomatorTestRunner.java:160)
info: [debug] [UIAUTOMATOR STDOUT] at com.android.uiautomator.testrunner.UiAutomatorTestRunner.run(UiAutomatorTestRunner.java:96)
info: [debug] [UIAUTOMATOR STDOUT] at com.android.commands.uiautomator.RunTestCommand.run(RunTestCommand.java:91)
info: [debug] [UIAUTOMATOR STDOUT] at com.android.commands.uiautomator.Launcher.main(Launcher.java:83)
info: [debug] [UIAUTOMATOR STDOUT] at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
info: [debug] [UIAUTOMATOR STDOUT] at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:243)
info: [debug] [UIAUTOMATOR STDOUT] at dalvik.system.NativeStart.main(Native Method)
info: [debug] [UIAUTOMATOR STDOUT] Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
info: [debug] [UIAUTOMATOR STDOUT] at libcore.io.Posix.open(Native Method)
info: [debug] [UIAUTOMATOR STDOUT] at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
info: [debug] [UIAUTOMATOR STDOUT] at libcore.io.IoBridge.open(IoBridge.java:393)
info: [debug] [UIAUTOMATOR STDOUT] ... 25 more
info: [debug] [BOOTSTRAP] [debug] Command returned error:java.lang.RuntimeException: Failed to Dump Window Hierarchy
info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":"Failed to Dump Window Hierarchy","status":13}
@seveniruby 问一下最新版本啥时候出来呀
请问,我能成功运行,但是执行起来很慢,一直停在一个页面,一会 swipe 一会 refresh ,基本没有动过
Error while parsing file:freemind.main.XMLParseException: XML Parse Exception during parsing of a map element at line 2: Expected: =
freemind 报错
不是很明白要怎么使用这个自动遍历工具。。。。
我想苹果真机来遍历,求一个详细的说明。只有一个 jar 包,还有那个 json 配置文件我要去哪里找。
#148 楼 @lengyao88 网盘里不是有文档吗
#150 楼 @lengyao88是啊,遍历安卓应用
#148 楼 @lengyao88 详细文档介绍
一份未完成的文档
百度网盘: http://pan.baidu.com/s/1c8yjgi
新浪微盘: http://vdisk.weibo.com/s/aii55uMrHRamh
#154 楼 @lengyao88 -c 指向你自己写的 json 配置文件 你去看看这个 pdf
#156 楼 @lengyao88 java -jar appcrawler-1.2.1.jar -p ios -a ios.app 文件地址或 URL,建议看看文档,文档写的更清楚。
iPhone 6 (iOS 9.2) 我要去哪里写配置指定这个模拟器
#160 楼 @lengyao88 你先看下文档. 文档里面已经写了.
#161 楼 @seveniruby
iOS 遍历
模拟器运⾏
启动 appium
appium --session-override
开始遍历
appcrawler -c src/universal/conf/xueqiu.json -p ios -a /Users/s
真机运⾏
使⽤ xcode 编译源代码. 使⽤开发证书才能做⾃动化. 编译出真机可⾃动化
的.app 包
appcrawler -c src/universal/conf/xueqiu.json -p ios -a /Users/s
#161 楼 @seveniruby 文档里面是这样写的
#161 楼 @seveniruby xueqiu.json 这个配置怎么写,我确实没看到有。
#164 楼 @lengyao88 无效回帖太多了, 你去加 appcrawler 的群讨论吧.
#161 楼 @seveniruby QQ 群号是多少
#166 楼 @lengyao88 翻以前的回帖就看到了 运行特定设备得首先有个设备. 其次是需要 appium 的基础.
appium 可以设定运行在什么设备上. 比如指定 iOS 设备你得用 Appium -U 指定. 或者通过--capability 来指定. 配置模板这里的确没提供. 等新版本吧.
我想问一下,这个的遍历覆盖率大概能到多少呢
#130 楼 @seveniruby 好的,谢谢
我在选定了自己的应用做遍历,然后转到了浏览器,现在在对浏览器做遍历,这个怎么破
我通过 java -jar appcrawler-1.2.1.jar -a xx.apk -o demo/ --capability appActivity=xxxx 启动后,appium 返回错误,提示信息如下:
UiAutomator did not shut down fast enough, calling it gone
[debug] Cleaning up android objects
[debug] Cleaning up appium session
Failed to start an Appium session, err was: Error: Could not find zipalign in tools, platform-tools, or supported build-tools under "F:\Android\android-sdk\android-sdk-windows"; do you have the Android SDK installed at this location?
[debug] Error: Could not find zipalign in tools, platform-tools, or supported build-tools under "F:\Android\android-sdk\android-sdk-windows"; do you have the Android SDK installed at this location?
[object Object].ADB.checkSdkBinaryPresent (C:\Program Files (x86)\Appium\node_modules\appium\node_modules\appium-adb\lib\adb.js:108:10)
[object Object].ADB.checkZipAlignPresent (C:\Program Files (x86)\Appium\node_modules\appium\node_modules\appium-adb\lib\adb.js:146:8)
[object Object].ADB.zipAlignApk (C:\Program Files (x86)\Appium\node_modules\appium\node_modules\appium-adb\lib\adb.js:457:8)
[object Object]. (C:\Program Files (x86)\Appium\node_modules\appium\node_modules\appium-adb\lib\adb.js:496:10)
ChildProcess.exithandler (child_process.js:742:7)
ChildProcess.emit (events.js:110:17)
maybeClose (child_process.js:1015:16)
Process.ChildProcess._handle.onexit (child_process.js:1087:5)
[debug] Responding to client with error: {"status":33,"value":{"message":"A new session could not be created. (Original error: Could not find zipalign in tools, platform-tools, or supported build-tools under \"F:\Android\android-sdk\android-sdk-windows\"; do you have the Android SDK install
this location?)","origValue":"Could not find zipalign in tools, platform-tools, or supported build-tools under \"F:\Android\android-sdk\android-sdk-windows\"; do you have the Android SDK installed at this location?"},"sessionId":null}
按照这错误提示信息来看,说在 android sdk 目录下,找不到相应的 ools, platform-tools, build-tools 目录,但实际上,这些目录是存在的,且环境配置是没有问题,有人遇到过这种问题吗,可以提供一些思路解决吗?
有 github 地址了不
#170 楼 @autotester native 跳转到 webview 貌似破不了吧
#170 楼 @autotester 点到哪跳出的, 你可以把那个控件设置为黑名单. 1.3.x 版本才支持屏蔽对外跳出.
安卓,已经稳定使用了,但是 ios 跑起来有点问题,一直停在一个页面,一会 swipe 一会 refresh ,基本没有动过
另外,看过类似 crash monkey 的工具 有个 html 报告,这个好像没把?
不错,已经发现一个 crash 问题 。 感谢
#174 楼 @seveniruby 什么时候出个版本内测下,下周需要用到截图 。
代码很给力,只不过为什么没有详细的安装步骤。参数输出的时候可不可以设置隐藏
LZ 这是你库的问题吧?
很给力,跑通了,给应用登录配置文件时,根据文档写的 json 文件,运行出错,期待配置文件指导
#179 楼 @freshtester 同学,你有遇到过我这个问题吗?这个感觉是 LZ 的库在解析的时候出了问题吧,App Crawler *** FAILED *** org.xml.sax.SAXParseException: Character reference "�" is an invalid XML character.
话说,LZ 现在都七月底了,还开源么?
@luyuan 没有遇到你这个问题额,我前面环境搭建,跑通都很顺畅,就在待测应用需要登录,然后需要使用配置文件,就出现这个错误了,但是看这报错,又不知道怎么解决
#186 楼 @seveniruby 哇,期待,八月中旬能确定下来吗?
#190 楼 @archy5947 你为什么要大开 mm?
#190 楼 @archy5947 之前别人报告过了, 是因为有特殊字符我没处理. 下个版本改进
@seveniruby : 安装的时候,是不是会修改签名文件?我这边安装完后,提示包会非法包。如果直接安装同样的 apk,则不会出现问题。--- 应该是 Appium 安装的问题。
#202 楼 @FZTooDoo 没那么复杂. 你犯了几个忌讳
为了不再惹事端, 我已经又改成付费入群了