下载appclawler

下载地址:https://pan.baidu.com/s/1dE0JDCH#list/path=%2F

查看帮助文档:

java -jar appcrawler-2.4.0-jar-with-dependencies.jar

Usage: appcrawler [options]

  -a, --app <value>        Android或者iOS的文件地址, 可以是网络地址, 赋值给appium的app选项
-e, --encoding <value> set encoding, such as UTF-8 GBK
-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信息
--demo 生成demo配置文件学习使用方法
--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

生成demo.yaml例子

java -jar appcrawler-2.4.0-jar-with-dependencies.jar --demo

---
pluginList: []
saveScreen: true
reportTitle: "雪球自动化遍历"
resultDir: "./test"
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.xueqiu.android
appActivity: .view.WelcomeActivityAlias
testcase:
name: "TesterHome AppCrawler"
steps:
- xpath: 行情
action: click
- xpath: 龙虎榜
action: click
then:
- //*[contains(@text,'沪深上榜个股')]
selectedList:
- xpath: "//*[contains(name(), 'Text') and @clickable='true' and string-length(@text)<10]"
- xpath: "//*[@clickable='true']/*[contains(name(), 'Text') and string-length(@text)<10]" firstList: []
lastList:
- xpath: "//*[@selected='true']/..//*"
- xpath: "//*[@selected='true']/../..//*" backButton:
- given: []
when: null
then: []
xpath: "Navigate up"
action: null
actions: []
times: 0
triggerActions:
- xpath: 净买入
times: 10
- xpath: 总成交
times: 10
- 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: []

启动已经安装过的app

java -jar appcrawler-2.4.0-jar-with-dependencies.jar --capability "appPackage=com.xueqiu.android,appActivity=.view.WelcomeActivityAlias"

定位模式xpath

xpath:
//*[@resource-id=‘xxxx’]
//*[contains(@text, ‘密码’)]
正则:
^确定$
^.*输入密码
包含:

输入
密码

自动化遍历支持

    selectedList:需要被遍历的元素范围
firstList:优先被点击
lastList:最后被点击
tagLimitMax:同祖先(同类型)的元素最多点击多少
backButton:当所有元素都被点击后默认后退控件定位
blackList:黑名单
maxDepth: 6 遍历的最大深度

触发器

triggerActions:
需要特定次数的触发动作
通常用于处理弹框
xpath: 指定具体按钮
action:动作
times:规则的使用次数

动作支持action

    “” 只是截图记录
back 后退
backApp 回退到当前的app 默认等价于back行为 可定制 monkey 随机事件
xxx() 执行代码
Thread.sleep(3000)
driver.swipe(0.9, 0.5, 0.1, 0.5) click
longTap
非以上所有行为是输入 xx ddd

与传统WebDriver的不同点

WebDriver:
根据id class xpath进行定位
直接截图
AppCrawler:ReactWebDriver模式:
先getPageSource获取所有的元素列表
根据配置好的宽泛的xpath直接选择元素
然后再生成匹配到的每个元素的唯一定位xpath表达式或者id定位表达式
然后调用appium定位并执行action
截图时增加对选择控件的高亮区分

配置文件参考

https://github.com/seveniruby/AppCrawler/blob/2.3.1/src/main/scala/com/testerhome/appcrawler/CrawlerConf.scala

package com.testerhome.appcrawler

import java.io.File

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import org.openqa.selenium.interactions.Actions import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import scala.io.Source /**
* Created by seveniruby on 16/1/6.
*/
class CrawlerConf {
/** 插件列表,暂时禁用,太高级了,很多人不会用 */
var pluginList = List[String]()
/** 是否截图 */
var saveScreen = true
var reportTitle = ""
/** 结果目录 */
var resultDir = ""
/**在执行action后等待多少毫秒进行刷新*/
var waitLoading=500
var waitLaunch=6000
//var tagLimit=scala.collection.mutable.Map[String, Int]()
var showCancel = true
/** 最大运行时间 */
var maxTime = 3600 * 3
/** 默认的最大深度10, 结合baseUrl可很好的控制遍历的范围 */
var maxDepth = 10
/** sikuli的数据 */
//var sikuliImages=""
//todo: 通过数据驱动,支持多设备
/** appium的capability通用配置 */
var capability = Map[String, Any](
//默认不清空数据,防止有人用于微信和qq
"noReset" -> "true",
"fullReset" -> "false",
) //测试用例
var testcase = ReactTestCase(
name = "TesterHome AppCrawler",
steps = List[Step](
Step(xpath = "/*", action = "Thread.sleep(5000)")
)
) /** 默认遍历列表,xpath有用,action暂时没启用*/
var selectedList = ListBuffer[Step](
Step(xpath="//*[contains(name(), 'Button')]"),
//android专属
Step(xpath="//*[contains(name(), 'Text') and @clickable='true' and string-length(@text)<10]"),
Step(xpath="//*[@clickable='true']/*[contains(name(), 'Text') and string-length(@text)<10]"),
Step(xpath="//*[contains(name(), 'Image') and @clickable='true']"),
Step(xpath="//*[@clickable='true']/*[contains(name(), 'Image')]"),
//ios专属
Step(xpath="//*[contains(name(), 'Image') and @name!='']"),
Step(xpath="//*[contains(name(), 'Text') and @name!='' and string-length(@label)<10]"),
)
/** 优先遍历元素 */
var firstList = ListBuffer[Step](
)
/** 最后遍历列表 */
var lastList = ListBuffer[Step](
Step(xpath="//*[@selected='true']/..//*"),
Step(xpath="//*[@selected='true']/../..//*")
)
/** 后退按钮标记, 主要用于iOS, xpath */
var backButton = ListBuffer[Step](
Step(xpath="Navigate up")
) //todo: 去掉triggerAction
/** 引导规则. name, value, times三个元素组成 */
var triggerActions = ListBuffer[Step](
Step(xpath="share_comment_guide_btn")
) //自动生成的xpath表达式里可以包含的匹配属
var xpathAttributes = List("name", "label", "value", "resource-id", "content-desc", "instance", "text")
/** 先按照深度depth排序,再按照list排序,最后按照selected排序。后排序是优先级别最高的 */
var sortByAttribute = List("depth", "list", "selected")
//可选 default|android|id|xpath,默认状态会自动判断是否使用android定位或者ios定位
var findBy="default"
/** 用来确定url的元素定位xpath 他的text会被取出当作url因素 */
var defineUrl = List[String]()
/** 设置一个起始url和maxDepth, 用来在遍历时候指定初始状态和遍历深度 */
var baseUrl = List[String]()
var appWhiteList = ListBuffer[String]()
/** url黑名单.用于排除某些页面 */
var urlBlackList = ListBuffer[String]()
var urlWhiteList = ListBuffer[String]()
/** 黑名单列表 matches风格, 默认排除内容是2个数字以上的控件. */
var blackList = ListBuffer[Step](
Step(xpath=".*[0-9]{2}.*")
) //在重启session之前做的事情
var beforeRestart=ListBuffer[String]()
//在执行action之前和之后默认执行的动作,比如等待
var beforeElement = ListBuffer[Step](
Step(xpath="/*", action="Thread.sleep(500)")
)
var afterElement = ListBuffer[Step]()
/**是否需要刷新或者滑动*/
var afterPage = ListBuffer[Step]()
//afterPage执行多少次后才不执行,比如连续滑动2次都没新元素即取消
var afterPageMax=2
//相似控件最多点击几次
var tagLimitMax = 2
//个别控件可例外
var tagLimit = ListBuffer[Step](
//特殊的按钮,可以一直被遍历
Step(xpath = "确定", times = 1000),
Step(xpath = "取消", times = 1000),
Step(xpath = "share_comment_guide_btn_name", times=1000)
)
//只需要写given与then即可
var assertGlobal = List[Step]() def loadByJson4s(file: String): Option[this.type] = {
if (new java.io.File(file).exists()) {
println(s"load config from ${file}")
println(Source.fromFile(file).mkString)
Some(TData.fromYaml[this.type](Source.fromFile(file).mkString))
} else {
println(s"conf file ${file} no exist ")
None
}
} def save(path: String): Unit = { /*
//这个方法不能正确的存储utf8编码的文字
implicit val formats = DefaultFormats+ FieldSerializer[this.type]()
val file = new java.io.File(path)
val bw = new BufferedWriter(new FileWriter(file))
log.trace(writePretty(this))
log.trace(write(this))
bw.write(writePretty(this))
bw.close()
*/ val file = new java.io.File(path)
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
mapper.writerWithDefaultPrettyPrinter().writeValue(file, this)
println(mapper.writeValueAsString(this))
} def toJson(): String = {
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(this) } def toYaml(): String = {
val mapper = new ObjectMapper(new YAMLFactory())
mapper.registerModule(DefaultScalaModule)
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(this)
} def loadYaml(fileName: File): CrawlerConf = {
val mapper = new ObjectMapper(new YAMLFactory())
mapper.registerModule(DefaultScalaModule)
mapper.readValue(fileName, classOf[CrawlerConf])
} def loadYaml(content: String): Unit = {
val mapper = new ObjectMapper(new YAMLFactory())
mapper.registerModule(DefaultScalaModule)
mapper.readValue(content, classOf[CrawlerConf])
} def load(file: String): CrawlerConf = {
load(new File(file)).get
} //如果没有显式配置参数,那么就会用默认值代替
def load(file: File): Option[CrawlerConf] = {
val content = Source.fromFile(file, "UTF-8").getLines().mkString("\n")
file.getName match {
case json if json.endsWith(".json") => {
Some(TData.fromJson[CrawlerConf](content))
}
case yaml if yaml.endsWith(".yml") || yaml.endsWith(".yaml") => {
Some(TData.fromYaml[CrawlerConf](content))
}
case path => {
println(s"${path} not support")
None
}
}
}

自动化遍历-appcrawler的更多相关文章

  1. AppCrawler自动化遍历使用详解(版本2.1.0 )

    AppCrawle是自动遍历的app爬虫工具,最大的特点是灵活性,实现:对整个APP的所有可点击元素进行遍历点击.   优点: 1.支持android和iOS, 支持真机和模拟器 2.可通过配置来设定 ...

  2. AppCrawler自动化遍历使用详解(版本2.1.0 )(转)

    AppCrawle是自动遍历的app爬虫工具,最大的特点是灵活性,实现:对整个APP的所有可点击元素进行遍历点击.   优点: 1.支持android和iOS, 支持真机和模拟器 2.可通过配置来设定 ...

  3. app遍历——appCrawler的使用

    1.appCrawler环境配置 1.1 apkinfo获取安装包的报名和mainActivity https://github.com/codeskyblue/apkinfo/releases 使用 ...

  4. APPcrawler基础原理解析及使用

    一.背景 一年前,我们一直在用monkey进行Android 的稳定性测试 ,主要目的就是为了测试app 是否会产生Crash,是否会有ANR,页面错误等问题,在monkey测试过程中,实现了脱离Ca ...

  5. 移动APP漏洞自动化检测平台建设

    移动APP漏洞自动化检测平台建设   前言:本文是<移动APP客户端安全笔记>系列原创文章中的第一篇,主要讲的是企业移动APP自动化漏洞检测平台建设,移动APP漏洞检测发展史与前沿技术,A ...

  6. 用java代码遍历excel文件并回显

    今天需要完成282个指标,分析后发现好多都是可复用的字段和方法,生成的dao类也是很多重复的代码,所以写下了简单的自动化遍历excel的test方法, excel业务逻辑如下,用了 HSSFSheet ...

  7. 测评:华为最新移动应用/APP测试工具MobileTest

    一.目前移动应用/App的测试痛点及可选方案 移动互联网市场进入下半场,同质化竞争激烈,平均获客成本增加.屏幕不适配.闪退.无响应.UI异常等兼容性问题严重影响用户体验,影响用户转化率和用户粘性.如何 ...

  8. 30多个Android 开发者工具 带你开发带你飞

    文中部分工具是收费的,但是绝大多数都是免费的. FlowUp 这是一个帮助你跟踪app整体性能的工具,深入分析关键的性能数据如FPS, 内存, CPU, 磁盘, 等等.FlowUp根据用户数量收费. ...

  9. 推荐五款Android 应用的自动化测试工具

    如今自动化测试已经应用到每天的测试中.这不足为奇,因为自动化测试在测试过程中节约了时间,还能避免包括人为因素造成的测试错误和遗漏. 自动化测试工具选择很多.一些是开源的,一些非常贵.一些自动化工具是几 ...

随机推荐

  1. [LeetCode]494. 目标和、416. 分割等和子集(0-1背包,DP)

    题目一 494. 目标和 给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S.现在你有两个符号 + 和 -.对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前 ...

  2. JavaScript中常用的数据输出方式解析

    在js中,一般使用如下几种方式进行数据的输出: 1. 在浏览器的控制台输出 浏览器F12打开浏览器控制台(一般前端开发人员必备浏览器为谷歌浏览器,下面就以谷歌浏览器为例对控制台尽心解析): 1.1 E ...

  3. 【好消息】博客迁移到github,求关注,求star,求支持

    博客迁移到github 地址:https://github.com/dirkhe1051931999/hjBlog

  4. javac中不引人注目的编码小坑

    来看下面这段java程序: public class Test{ public static void main(String[] args){ System.out.println("哈哈 ...

  5. 基于MAXIMO的发电行业EAM解决方案

    1. 行业背景 随着我国以“厂网分开,竞价上网”为特点的电力市场的起步和发展,发电厂.发电集团成为独立企业参与市场竞争,原有的“生产型”管理模式已经不再适应市场的需求.发电企业在重视安全质量.保证电力 ...

  6. JVM参数总结

    官方文档 堆参数: -Xms: 堆的初始值,例如 -Xmx2048,初始堆大小为 2G -Xmx: 堆的最大值,例如 -Xmx2048M,允许最大堆内存 2G -Xmn: 新生代大小 -XX:Surv ...

  7. Python列出指定目录下的子目录/文件或者递归列出

    1.python只列出当前目录(或者指定目录)下的文件或者目录条目 import os files,dirs=[],[] for item in os.listdir(): if os.path.is ...

  8. java ConcurrentHashMap和CopyOnWriteArrayList解决并发问题

    ConcurrentHashMap 一.hashtable.hashmap.ConcurrentHashMap 1.线程不安全的HashMap 因为多线程环境下,使用Hashmap进行put操作会引起 ...

  9. Redis学习(三)java使用redis

    一.操作步骤 Redis除了命令行操作以外,还可以通过java代码进行操作,流程如下: 下载Jedis依赖包,并丢入工程中合适的位置 在Maven中引入redis的包 <!--引入redis包- ...

  10. Mall电商实战项目发布重大更新,全面支持SpringBoot 2.3.0

    1. 前言 前面近一个月去写自己的mybatis框架了,对mybatis源码分析止步不前,此文继续前面的文章.开始分析mybatis一,二级缓存的实现. 附上自己的项目github地址:https:/ ...