AppCrawler AppCrawler 自动遍历工具 1.2.1 版本

思寒_seveniruby · 2016年04月15日 · 最后由 思寒_seveniruby 回复于 2017年01月13日 · 27151 次阅读
本帖已被设为精华帖!

新版本已经更新到 1.5.0

https://testerhome.com/topics/5718
结贴

工具在筹备 1.4.0 版本的发布. 所以暂不回答大家各种重复的问题了. 我创建了一个 qq 交流群: 177933995 可自行加入

第四届线下沙龙回顾

3 月份高鹏 徐世钊 mingway 在阿里巴巴举办了第四届 TesterHome 线下沙龙
我在沙龙中分享了 AppCrawler 自动遍历工具的前世今生和一些 feature.
当时因为在完善一些细节. 所以没有放出来试用版本. 今天算是给大家补上吧.

ChangeLog

增加了一个实验性的自动化测试框架. 放出来也是想让大家当小白鼠
增加了自动化测试的支持. 可以在自动化中进入自动遍历.
增加了 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

新增自动化支持 demo

不是重复造轮子. 是 scalatest 自带的一个 selenium 的封装. 我之前在社区发过
我新增了三个关键词来简化测试步骤

常用关键字

see 定位方法
tree 元素访问方法
send 发送文字
click on 点击

see

唯一的元素定位方式.

see 是引用了<阿凡达>电影里面一句台词"I See You". 它的作用是当你看到一个控件, 你应该可以根据看见的东西就可以定位它, 无须借助其他工具或者使用 findElementByXXX 之类的函数.

比如有个 Button, 名字是"登录", 它的 id 是 account, 定位它可以通过如下多种方式的任何一种

  • see("登录")
  • see("登")
  • see("录")
  • see("acc")
  • see("account")
  • see("//UIAButton[@id="account"]")

如果当前界面中存在了有歧义的控件, 比如其他一个名字为"登录"的输入框. 那么上述定位方法中定位中两个控件的定位方法会失效, 你需要自己调整即可.
关于元素定位你只需要用 see 这个方法即可.

tree

打印当前界面布局结构. 是个格式化的 xml 内容.

如果传入一个参数 则会打印符合你给定关键词或者 xpath 定位的元素列表

这个关键词是为了让你摆脱各类的元素定位工具, 比如 appium inspector, uiautomator 之类的工具.

  • tree() 输出当前的 Android 或者 iOS 的 dom 树结构.
  • tree("登录") 输出满足 see("登录") 的所有控件的所有属性, 以及定位到相关控件的 xpath 表达式. 不用自己写了 ``` # 这是 xpath 表达式 xpath=Some(//UIAApplication[@name="雪球" and @path="/0"]/UIAWindow[@path="/0/0"]/UIAStaticText[@name="注册" and @path="/0/0/4"])

# 这是对应的控件的所有属性
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" : [ ]
}

后记

很多人都在反馈相同的问题, 我工作很忙, 所以就结贴了.
列举下大家反馈的问题. 然后等新版本吧.

  • xml 文件有特殊字符导致 freemind 打不开
  • windows 记事本插入 bom 字符导致读取 json 失败
  • getPageSource 有 xml 的特殊字符导致定位有问题
  • windows 上运行环境变量未设置对
  • windows 上 jdk 版本不对

各位看官如果阅读的赏心悦目的话, 记得点击帖子下方的"打赏"按钮给打个赏.

老帖介绍: https://testerhome.com/topics/4151

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 194 条回复 时间 点赞

沙发,利器啊

厉害,这个相当实用

还在审核中,等通过了试用一下

#3 楼 @pengwei 还要申请啊?@ 思寒

还在审核中。。。

#5 楼 @lihuazhang 上传到新浪微盘了. 新浪貌似要审核. 我一会也传百度网盘一份.

#4 楼 @lihuazhang 下载地址的微盘显示还在审核,现在还下载不了

#8 楼 @seveniruby 辛苦啊,还是百度云快一些

终于等到了。。。。努力折腾一下 -___.-

输入命令,进行试用的过程中,报错了,请教下,是什么原因尼?

  • App Crawler *** FAILED *** org.openqa.selenium.remote.UnreachableBrowserException: Could not start a new session. Possible causes are invalid address of the remote server or browser start-up failure.

#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 的方法对截图下来的进行模式匹配,这样兼容性测试就是一套完整的了

21楼 已删除

赞,已用上

@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 的结果.

#38 楼 @budian 我没做混淆. 这个我就爱莫能助了, 可能你得着更好的反编译工具.

#43 楼 @huangke 有时间跟大家讲讲具体的技术实现, 不难

@seveniruby 非常期待啊!

brew install -g appium 应该是 npm ba

看起来很牛逼的样子,抽空使用一下

—— 来自 TesterHome 官方 安卓客户端

#48 楼 @seveniruby 楼主 新包好了嘛,期待中......

#18 楼 @seveniruby 哪个步骤不对么?

elementActions:
 {
    "action" : "click",
    "idOrName" : "我的",
    "times" : 3
  }

这个 action 是否支持滑动操作?

#52 楼 @michael_wang 暂不支持. 下个版本加上.

#51 楼 @taki 上面已经说了, 你的 activity 不存在, 可能你写错了

#54 楼 @seveniruby 我用你的那个链接 下载的雪球 我试试其他 apk 吧

#54 楼 @seveniruby 我把 -a 参数拿掉了, capability 加了包名可以了

#53 楼 @seveniruby 请问 apk 安装启动后出现闪退是什么问题?

如果是商城类型的 app,想让这个工具把每一篇商品详情内的所有控件都进行点击一遍,而不是点过一篇后,其他的就认为都是点过了,通过 conf 中的配置文件可以实现吗?

#58 楼 @michael_wang 可以, 这个需要重定义 url. 在 url 中加入详情页的标题就可以了. 这个目前没有放出来配置说明 其实就是定义那个 defineUrl 配置

#18 楼 @seveniruby 思寒,有没有一个详细的遍历配置的编写说明尼?现在不太清楚要怎么来编写~

#60 楼 @mistyrain 下个版本我增加一个自动生成默认的配置文件模板

@seveniruby 工具已经跑起来了,想到一个问题请教,就是已经安装在手机上的应用怎么跑,结果发现好像必须得有 app 的包啊,还是说我的配置错了??

#62 楼 @jackie 教程里面写了吧. 不写 app 就行了. 改用--capability 参数

#61 楼 @seveniruby 嗯,期待~下个版本预计什么时候更新尼?

@seveniruby 查看 help 提示是 --capability k1=v1,k2=v2... 然后我就用了上面截图中的命令 K1 和 K2 我是用的空格报错 然后得到你的肯定回复后我就多试了几下 把 K1 和 K2 中间价格逗号就 OK 了

匿名 #66 · 2016年04月27日

你好,问下在测试 iOS 应用时,安装应用后第一次启动系统都会弹出类似 “XX 想给您发送推送通知"弹窗,然后就无法遍历了,只能手动点允许或取消才能继续。这个有办法解决么?

#66 楼 @jusnic 目前的这个版本已经支持了. 我这边跑是没问题的

#64 楼 @mistyrain 已经交给一些人内测了.

匿名 #69 · 2016年04月27日

#67 楼 @seveniruby 如图这个提示会一直存在,导致无法正常遍历,然后显示 ScriptAgent 崩溃了。

#69 楼 @jusnic 我们的 app 也是一样的提示. 是可以自动点过去的 这个功能是 appium 提供的. 这个得自己想办法解决了. 可能跟你的环境有关.

匿名 #71 · 2016年04月27日

#70 楼 @seveniruby 意思在配置文件中配置规则点击是没用的?和 appium 版本有关?我的用的 iphone6 9.0+Mac OS 10.11+appium 1.4.13,能问你的环境不

匿名 #72 · 2016年04月27日

没找到 1.5.2 的 mac 版。。。只有源码

@seveniruby ,我的也是 1.4.16,运行有问题,能给个 1.5.1 的版本吗?

匿名 #75 · 2016年04月29日

#70 楼 @seveniruby 你好,请问有没有参数可以设置不输出结果?

什么时候开源,最近有个任务正好用到,再不开源只能自己做了

运行没多久截图的时候就报错了:

#77 楼 @olivia 应该是控件名字为特殊符号导致的吧. 我简单的把控件的属性转换成了文件名去保存每次控件相关的数据 如果特殊符号太多会有问题. 我下个版本解决下吧. 1.3.0 版本快要发布了

我是小白,这个怎么用

试用下

@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"

#82 楼 @fwcco2605 @finelucky

我也是用的中文, 没问题. 你们是不是都是 windows. windows 保存的时候有时候格式不标准. 可能会引发问题. 估计需要框架做个兼容才行.

{
    "action" : "click",
    "idOrName" : "点此.*",
    "times" : 0
  }, {
    "action" : "click",
    "idOrName" : "不保存",
    "times" : 0
  }, 

#76 楼 @quqing 7 月份吧. 大会的时候, 给大会助威.

#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 也不靠谱,页面有细微的变化就变了,窗口迁移处理和跳窗处理你有好的解决方案吗?

#91 楼 @quqing 恩. 这就是我 appcrawler 里面的 defineUrl 的用途. 抽象为合理的 url 即可.

ios 的跳窗处理更蛋疼了,感觉 defineUrl 还是指标不治本,还是我理解的有问题。。。

#91 楼 @seveniruby 刚才试验了下任务栈黑名单机制和任务栈自动重置的策略,现在对窗口迁移和跳窗的判断依赖小了很多,稳定性显著提高了

#94 楼 @quqing 我是用 scala 写的. 行业里面需要有一个 java 写的框架. 所以我是鼓励你自己设计一个的. 你可以把你们公司的邮箱告诉我, 我加你到项目.

@seveniruby 现在代码在 github?private?

#96 楼 @chenDoInG 还未到开源状态, 会先开放给一些技术高手. private

#95 楼 @seveniruby 公司邮箱不能访问外网,个人邮箱:quqing0930@126.com

#92 楼 @seveniruby 我又想到一个方法,判断窗口是否迁移,待会实验一把
把操作前、操作后的两个窗口文件按顺序解析出可执行节点,每个节点用 xpath 的绝对路径做唯一标识,保存在两个集合,然后进行差异性比较。举个例子:如果差异率小于 10%(按实际情况自己配置),则认为是 同一窗口下的任务,去重后合并成一个新的任务栈

#99 楼 @quqing 我早就想过了. 哈哈, 你先自己摸索下吧. 也许能找到不一样的路.

#99 楼 @seveniruby 看样子,你也踩了不少坑

#100 楼 @seveniruby 我现在跑的挺稳定的,唯一的遗憾是这个问题没彻底解决,导致部分窗口的任务可能重复跑影响效率

#102 楼 @quqing 方法总比问题多. 思考的越多, 越接近真相

#103 楼 @seveniruby 任务催的紧,两星期没睡好觉,马不停蹄的摸索,踩坑,填坑,今天算是稳定版交差了,接下来是核心算法的优化了,你的文章给了我启发,少走了弯路

额。。我没有做过移动端的测试。所以我问个无知的问题。自动遍历解决了什么问题?检测 crash?

#105 楼 @ycwdaaaa 文档里面有介绍. 检测 UI 兼容性问题和 crash, 以及其他的接口异常之类的问题.

#92 楼 @seveniruby 参考了几款 app,defineUrl 可能不能解决一些特殊情况,例如:有的窗口有 title,有的窗口没有 title,有的窗口 title、tab 完全一样,选择不同 tab 的内容不一样,有的 app 窗口内控件的命名规则太随意,很难用一个 defineUrl 适配所有窗口,可能还有许多未知的情况。
今天总结后又想到一个方法,以 android 为例:按顺序解析 xml 所有节点,但只取除坐标之外的属性和 text 拼接成字符串,默认取前面 30 个节点的内容(用户通过配置自定义)生成 md5,觉得这样的通用性和辨识率会大大提高

滑动操作 有没有什么好的思路?如何跟点击完美结合?

试用了下,app 一开始就得登录的情况,怎么解决。

#109 楼 @shijin880921 看文档, 里面解决办法. 使用触发器规则

匿名 #111 · 2016年05月23日

请问一下可以控制不走 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: =

匿名 #114 · 2016年05月24日

@seveniruby 目前测试 iOS app 过程中遇到一个问题,遍历过程中碰到用浏览器打开等跳转到其它 app 的问题,点击后跳转到浏览器 app 了,有什么方法自动回退到原来的 app 么?

匿名 #115 · 2016年05月26日

@seveniruby 运行时遇到无法启动 Activity 的问题(见下图),是否是需要加参数去控制

请问,app 需要登录用户名和密码输入的,如何操作才可以记录录制呢?

@eveniruby

匿名 #117 · 2016年06月01日

安装应用后 iOS 会弹出 是否允许通知推送的 系统对话框,这个 appium 需要配置那些参数呢?waitForAppScript : “true;”,等等我试了好多,都不行。有碰到的么?

匿名 #118 · 2016年06月03日

你好问一下。跟踪日志里有 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 搞错了.
第二个问题可以通过配置文件来设定是左划还是右划多少次.
第三个问题是默认只访问简单的文本和图片元素. 如果你们的元素特殊, 需要自己修改配置文件改进下.

匿名 #122 · 2016年06月04日

#119 楼 @seveniruby 原来是这样啊。那需要在配置文件怎么去除呢?我看了你的文档,好像提到插件开发的地方是空白。不太懂怎去掉,谢谢

@seveniruby 这个自动遍历现在还不在 github 上?

#123 楼 @lihuazhang 中国移动测试大会的时候放上去, 现在还是 gitlab 上, 只是分享给了少数人.

#122 楼 @guaixiaomei pdf 版本的文档里面有提到吧. plugins 里面去掉即可

@seveniruby 请教大神,最近在学习 Appium 看到您自动化遍历的工具,之前自己也思考过实现遍历功能,想了解下实现的思路是怎样的~还望赐教!

#127 楼 @lihuazhang 是啊. 到时候会有黑客圈的人用这个. 我得赶紧放个新版本出来. 开源等大会的时候再宣布


请问,这是什么原因?

#129 楼 @cy_suncheng 这个版本的 bug, app 里面有特殊字符会导致拼装 xml 失败. 下个版本解决

恒温 将本帖设为了精华贴 06月26日 20:53
132楼 已删除

好东西,学习中

楼主,想问下这个遍历过程中有没有做某些屏蔽,比如遍历图库 app,测试过程中可能会点到 “全选”,然后 “删除”,这样造成被测资源为空的情况,遍历的有效性很低了
想问楼主这种情况有做兼容吗?
谢谢!

#134 楼 @CrystalChen1017 支持, 自己看下文档吧.

之前看了些文章,1、说自动化遍历可以通过 xml 属性中基于 clickable 来实现~不知道 appCrawler 这个实现原理是?
2、如果遍历过程中出现 app 崩溃,闪退,这 appCrawler 会重启在执行嘛?

appCrawler 如果深度遍历,提个建议,能不能形成二叉树遍历模型图,这样更容易看出来遍历的过程和进度。。。。


跑了一个小时报错了,观察当前页面还可以继续下划的。请问这是什么情况呢?

求 share 配置文件,conf.json 那个文件。。。

#139 楼 @leey 就是一个简单的 json 语法格式的啊。。。

思寒_seveniruby [该话题已被删除] 中提及了此贴 07月07日 17:46

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}

匿名 #144 · 2016年07月18日

@seveniruby 问一下最新版本啥时候出来呀

请问,我能成功运行,但是执行起来很慢,一直停在一个页面,一会 swipe 一会 refresh ,基本没有动过

#113 楼 @qd_wzg 一样的问题,有解决吗?

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 网盘里不是有文档吗

#149 楼 @yoegg 你是用来遍历安卓应用是吗?

#149 楼 @yoegg Error: Invalid or corrupt jarfile /Users/cly/Documents/appcrawler-1.2.1.jar

#150 楼 @lengyao88是啊,遍历安卓应用

#148 楼 @lengyao88 详细文档介绍

一份未完成的文档
百度网盘: http://pan.baidu.com/s/1c8yjgi
新浪微盘: http://vdisk.weibo.com/s/aii55uMrHRamh

#153 楼 @yoegg appcrawler -c conf/xueqiu.json -p iOS
我下的是 jar 包啊,这个命令是不行的。

#154 楼 @lengyao88 -c 指向你自己写的 json 配置文件 你去看看这个 pdf

#155 楼 @yoegg appcrawler 找不到这个命令。。。

#156 楼 @lengyao88 java -jar appcrawler-1.2.1.jar -p ios -a ios.app 文件地址或 URL,建议看看文档,文档写的更清楚。

#157 楼 @yoegg json 配置文件的写法,文档没看到有啊。

#157 楼 @yoegg 给力. 工具文档等新版本吧. 文档里面最详细. 这几天正在做新版本和拆分代码开源

#157 楼 @yoegg

  • App Crawler *** FAILED *** org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: Could not find a device to launch. You requested 'iPhone 6 (9.2) [', but the available devices were: "Apple TV 1080p (9.2) DAB3248A-624A-4710-80CA-369D97AB5CA6","iPad 2 (9.3) 30E7C063-8218-445D-9586-E12764218676","iPad Air (9.3) 7B19A7CB-A7F1-49D9-9BE8-0C0A2183BCD2","iPad Air 2 (9.3) AE713A51-57DD-4DF7-AF7C-5C407BBFA654","iPad Pro (9.3) 6DD9013C-7162-4E99-8E56-A216750DB1F8","iPad Retina (9.3) 78E3792F-8E51-426F-8098-84FF8C664798","iPhone 4s (9.3) 6D681EA6-5A58-41A2-B2A5-CFAEFE8315C4","iPhone 5 (9.3) 0271473C-8241-45F8-AA89-68AB2A962B63","iPhone 5s (9.3) 4D63A6A7-455E-4524-A2AD-8945440A4763","iPhone 6 (9.3) E0B98126-B342-4EB3-BEAB-B76070248688","iPhone 6 Plus (9.3) 1A292B44-0593-4685-AB98-8CB58564A033","iPhone 6s (9.3) 9748E735-DBC1-4F79-AD77-5FEC0B47EF0D","iPhone 6s (9.3) + Apple Watch - 38mm (2.2) D8C3455A-8316-40D8-8D3C-D05F6E39489D","iPhone 6s Plus (9.3) 4E060382-8591-42F3-9482-9A950189BCF8","iPhone 6s Plus (9.3) + Apple Watch - 42mm (2.2) 220F18DA-1BA4-470C-9F5E-6BD5584D67D3" Command duration or timeout: 2.41 seconds Build info: version: 'unknown', revision: 'unknown', time: 'unknown' System info: host: 'clydeiMac.local', ip: '192.168.3.70', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.11.6', java.version: '1.8.0_91' Driver info: io.appium.java_client.ios.IOSDriver at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:206) at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:158) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:595) at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:42) at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1) at io.appium.java_client.ios.IOSDriver.execute(IOSDriver.java:1) at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:242) at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:128) at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:141) at io.appium.java_client.DefaultGenericMobileDriver.(DefaultGenericMobileDriver.java:37) at io.appium.java_client.AppiumDriver.(AppiumDriver.java:160) at io.appium.java_client.AppiumDriver.(AppiumDriver.java:168) at io.appium.java_client.ios.IOSDriver.(IOSDriver.java:56) at IOSCrawler.setupAppium(IOSCrawler.scala:42) at Crawler.start(Crawler.scala:123) at AppCrawlerTestCase$$anonfun$1.apply$mcV$sp(AppCrawlerTestCase.scala:27) at AppCrawlerTestCase$$anonfun$1.apply(AppCrawlerTestCase.scala:11) at AppCrawlerTestCase$$anonfun$1.apply(AppCrawlerTestCase.scala:11) at org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:22) at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85) at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104) at org.scalatest.Transformer.apply(Transformer.scala:22) at org.scalatest.Transformer.apply(Transformer.scala:20) at org.scalatest.FunSuiteLike$$anon$1.apply(FunSuiteLike.scala:166) at org.scalatest.Suite$class.withFixture(Suite.scala:1122) at org.scalatest.FunSuite.withFixture(FunSuite.scala:1555) at org.scalatest.FunSuiteLike$class.invokeWithFixture$1(FunSuiteLike.scala:163) at org.scalatest.FunSuiteLike$$anonfun$runTest$1.apply(FunSuiteLike.scala:175) at org.scalatest.FunSuiteLike$$anonfun$runTest$1.apply(FunSuiteLike.scala:175) at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306) at org.scalatest.FunSuiteLike$class.runTest(FunSuiteLike.scala:175) at org.scalatest.FunSuite.runTest(FunSuite.scala:1555) at org.scalatest.FunSuiteLike$$anonfun$runTests$1.apply(FunSuiteLike.scala:208) at org.scalatest.FunSuiteLike$$anonfun$runTests$1.apply(FunSuiteLike.scala:208) at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:413) at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:401) at scala.collection.immutable.List.foreach(List.scala:381) at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401) at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:396) at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:483) at org.scalatest.FunSuiteLike$class.runTests(FunSuiteLike.scala:208) at org.scalatest.FunSuite.runTests(FunSuite.scala:1555) at org.scalatest.Suite$class.run(Suite.scala:1424) at org.scalatest.FunSuite.org$scalatest$FunSuiteLike$$super$run(FunSuite.scala:1555) at org.scalatest.FunSuiteLike$$anonfun$run$1.apply(FunSuiteLike.scala:212) at org.scalatest.FunSuiteLike$$anonfun$run$1.apply(FunSuiteLike.scala:212) at org.scalatest.SuperEngine.runImpl(Engine.scala:545) at org.scalatest.FunSuiteLike$class.run(FunSuiteLike.scala:212) at AppCrawlerTestCase.org$scalatest$BeforeAndAfterAllConfigMap$$super$run(AppCrawlerTestCase.scala:6) at org.scalatest.BeforeAndAfterAllConfigMap$class.liftedTree1$1(BeforeAndAfterAllConfigMap.scala:248) at org.scalatest.BeforeAndAfterAllConfigMap$class.run(BeforeAndAfterAllConfigMap.scala:247) at AppCrawlerTestCase.run(AppCrawlerTestCase.scala:6) at org.scalatest.Suite$class.execute(Suite.scala:843) at org.scalatest.FunSuite.execute(FunSuite.scala:1555) at AppCrawler$.main(AppCrawler.scala:160) at AppCrawler.main(AppCrawler.scala)

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 的群讨论吧.

#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 什么时候出个版本内测下,下周需要用到截图😂

#177 楼 @pacerron 哈哈. 不错. 目前使用起来还是有点复杂的.我也在想如何精简. 这个暂没有 html 报告. 我是直接使用的数据分析做各种分析. 毕竟这只是自己用的小工具.

#178 楼 @yoegg 梳理代码开源中.

代码很给力,只不过为什么没有详细的安装步骤。参数输出的时候可不可以设置隐藏

  • App Crawler *** FAILED *** org.xml.sax.SAXParseException: Character reference "&#55356" is an invalid XML character.

LZ 这是你库的问题吧?


很给力,跑通了,给应用登录配置文件时,根据文档写的 json 文件,运行出错,期待配置文件指导😟

#179 楼 @freshtester 同学,你有遇到过我这个问题吗?这个感觉是 LZ 的库在解析的时候出了问题吧,App Crawler *** FAILED *** org.xml.sax.SAXParseException: Character reference "&#55356" is an invalid XML character.

话说,LZ 现在都七月底了,还开源么?

#185 楼 @luyuan 流程已经在公司那了, 就等 github 上了.

@luyuan 没有遇到你这个问题额,我前面环境搭建,跑通都很顺畅,就在待测应用需要登录,然后需要使用配置文件,就出现这个错误了,但是看这报错,又不知道怎么解决

#186 楼 @seveniruby 哇,期待,八月中旬能确定下来吗?

#188 楼 @luyuan 模板我已经更新到帖子了. 1.3.x 的版本未对外公开.
接下来我要准备 1.4.0 的版本对外发布和代码的开源. 所以就暂不回答大家的提问了.

#175 楼 @pacerron 你好~问一下。你运行后的.mm 文件能打开吗?为什么我这边 freemind 打不开,报错:Error while parsing file:freemind.main.XMLParseException: XML Parse Exception during parsing of a map element at line 2: Expected: =

#190 楼 @archy5947 你为什么要大开 mm?

#190 楼 @archy5947 之前别人报告过了, 是因为有特殊字符我没处理. 下个版本改进

思寒_seveniruby 关闭了讨论 07月28日 15:08
陈恒捷 [该话题已被删除] 中提及了此贴 08月03日 11:42
狂师 [该话题已被删除] 中提及了此贴 08月05日 11:15

@seveniruby : 安装的时候,是不是会修改签名文件?我这边安装完后,提示包会非法包。如果直接安装同样的 apk,则不会出现问题。--- 应该是 Appium 安装的问题。

#196 楼 @qawow 不会修改包. 可能是你配置错了

198楼 已删除
202楼 已删除

#202 楼 @FZTooDoo 没那么复杂. 你犯了几个忌讳

  • 加群的提示消息你明显就没看. 上面写了加微信 testerhomer 要加群的口令.
  • 这 1.2.1 都很老的版本了. 最新的帖子是 1.7.0. 你明显也没好好的看帖子.
  • 那个群不是讨论自动化的, 是围绕 appcrawler 顺带自动化的.
  • 这个工具有点技术门槛. 没自动化基础想交流自动化技术的都不适合加群.
  • 这群目前是 199 人. 其中一半的人都是付费入群的. 另外一本是开启付费之前加群的
  • 群已经改成不收费好几个月了. 这个工具本身能给测试带来价值, 我也要付出时间回答问题. 就算收费不也是正常的嘛.

为了不再惹事端, 我已经又改成付费入群了

204楼 已删除
狂师 AppCrawler 工具试用问题收集及解决方法 中提及了此贴 06月12日 21:57
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册