Skip to content

Commit

Permalink
修复默认配置的错误。改进跳出app的判断逻辑。回到app的方式调整为launchApp。更新依赖。增加演示例子。
Browse files Browse the repository at this point in the history
  • Loading branch information
seveniruby committed Oct 28, 2017
1 parent 5d18e4a commit 9c9cd0f
Show file tree
Hide file tree
Showing 26 changed files with 294 additions and 318 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# 2.1.1[TODO]
支持从历史数据中寻找最优点击路径
支持web
支持游戏app遍历
- 支持从历史数据中寻找最优点击路径
- 支持web
- 支持游戏app遍历
- 跟进支持appium 1.7[完成]

# 2.1.0
### bugfix
Expand Down
7 changes: 2 additions & 5 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name := "AppCrawler"
version := "2.1.1"
version := "2.1.2"
scalaVersion := "2.12.3"

libraryDependencies ++= Seq(
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
//"org.scala-lang" % "scala-compiler" % scalaVersion.value,
"org.scala-lang" % "scala-library" % scalaVersion.value,
//"org.scala-lang" % "scala-reflect" % scalaVersion.value,
"io.appium" % "java-client" % "5.0.4",
Expand All @@ -27,9 +27,6 @@ libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.0.3" ,
"org.apache.directory.studio" % "org.apache.commons.io" % "2.4",
"org.scalatra.scalate" %% "scalate-core" % "1.8.0",
"com.sksamuel.elastic4s" %% "elastic4s-core" % "5.1.5",
"com.sksamuel.elastic4s" %% "elastic4s-xpack-security" % "5.1.5",
"org.elasticsearch.client" % "transport" % "5.1.2",
"org.apache.logging.log4j" % "log4j-core" % "2.7",
"macaca.webdriver.client" % "macacaclient" % "2.0.7",
"org.javassist" % "javassist" % "3.22.0-CR2",
Expand Down
126 changes: 126 additions & 0 deletions doc/霍格沃兹测试学院.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@


# 关于霍格沃兹测试学院
霍格沃兹测试学院是StuQ移动测试小班课的承办机构发展而来。
StuQ小班课是TesterHome社区与极客邦公司StuQ学院的合作项目,旨在以微盈利的方式传授测试技能知识推动移动测试的发展。
小班课经过了一年多的历练,已经服务了**数百名**测试行业的学员,获得了不俗的测试行业口碑,课程内容也越来越精良。
鉴于这个项目影响力越来越大,为了更好的服务学员,扩大社区影响力,项目运作团队正式更名为**霍格沃兹测试学院**

霍格沃兹测试学院课程体系
- 移动测试开发**快速进阶**课程
- 移动测试开发**强化训练**课程

### 移动测试开发培训快速进阶课程[线上直播课程] 26课时
线上授课,与极客邦StuQ学院合作,面向初中级测试工程师,实现测试开发能力的掌握,晚上授课为主,总共26课时。

### 移动测试开发培训强化训练课程 [线上线下同时支持] 40课时
线下线上同步授课,是快速进阶课程的加长版,提供更多强化训练,连续5个周日40课时。
会提供linux jenkins sonar docker elk appium stf等演练环境。
**学员也可带着自己公司的app来实训,让实训变的更有针对性**。确保课程后每位同学都能达到熟练的对自己公司的产品进行app自动化和接口自动化,提升公司的产品质量保证。

# 讲师阵容
六位讲师,皆来自于互联网一线公司。工作经验在5-10年。授课时有**助教**手把手指导。
思寒:十年工作经验,先后工作于阿里巴巴 百度 雪球
卡斯:十年以上工作经验,先后工作于华为,Testin
校长:十年以上工作经验,某著名互联网车企公司测试经理
大东:五年左右工作经验,前沪江网测试开发工程师
神秘美女讲师:八年工作经验,工作于Intel
阿飞:五年左右工作经验,社区技术达人,工作于某一线AI技术公司


# 授课形式
快速进阶课程的形式为在线直播,并支持一年内观看录播。

强化训练班支持**线上授课和线下授课**,北京本地同学可直接来地图标记的地点现场实训,讲师会手把手指导。
外地同学可以通过手机或电脑上的工具直连听课,讲师提供在线的答疑和远程指导。
授课内容提供课程视频回放,可无限观看。

# 课程受众
快速进阶班和强化训练班的主要区别是:
**强化训练班面向学渣和学痴,支持线下面对面授课和线上同步直播,每期五十人左右。面向没有测试开发基础的同学,提供手把手的指导确保掌握每个技术细节并落地应用**
**快速进阶班适合学痴和学霸,只支持在线直播授课,每期一百人左右。适合有测试开发基础的同学,提供最关键的技术讲解和演练,确保短时间掌握技术精髓和学习方向**

# 测试开发技能大纲
课程内容由思寒和校长等多位行业技术专家操刀,邀请了腾讯、阿里、百度、360等公司的测试技术专家进行了评估和改进。
保证学习的内容足够深入使用,实现让学员对测试开发技能有深入理解和应用的水平。

### 移动测试技术体系 思寒
- 移动测试基础
- 研发阶段的质量保证 白盒测试 代码审计 单元测试
- 测试阶段的质量保证 接口测试 专项测试 场景测试 业务测试
- 发布后的质量监控 接口监控 问题收集

### Bash课程基础 思寒
- Bash
- Linux和Android iOS的基本命令使用
- 脚本编写与自动化相关
- awk grep sed mail curl工具使用

### Appium自动化-Android 大东
- Appium安装
- Appium客户端安装
- Android自动化测试用例编写
- 自动化测试演练
- 自动化测试常见技术点分析

### Appium自动化-iOS 大东
- iOS自动化基础知识
- iOS自动化测试用例编写
- iOS自动化测试演练
- Appium流程分析与错误定位

### 自动遍历测试技术 思寒
- Monkey工具使用
- AppCrawler在Android上的遍历测试
- AppCrawler在iOS上的遍历测试分析
- 弹框处理与Watch机制
- Android与iOS dom分析
- XPath定位高级技巧

### 接口测试入门 校长
- 接口测试基本概念
- 接口测试用例编写
- 接口测试的cookie和session机制
- 接口测试断言机制 JsonPath与XmlPath
- 接口schema校验
- 接口测试演练

### 接口测试进阶 校长与思寒
- dubbo与数据库协议的接口测试
- excel xml等数据驱动的测试用例
- 测试用例和测试套件管理机制
- Jenkins与接口测试的集成
- 接口测试平台建设

### 持续集成
- Jenkins的搭建部署
- Jenkins workflow任务管理机制
- Jenkins与svn git的对接和代码构建
- Jenkins调用移动测试框架appium的演练
- Jenkins调用web测试框架selenium的演练
- Jenkins调用接口测试框架RestAssured的演练

### 持续集成进阶
- 持续集成 devops 持续交付讲解
- Jenkins 2.0 pipeline机制
- pipeline定义和使用
- blueocean的使用
- 自定义测试报告与图表

### docker容器技术 高飞
- Docker的基础和特点
- docker的生态体系
- 演练用docker搭建Jenkins
- 演练用docker搭建Selenium
- 演练用docker搭建sonarqube
- 演练用docker搭建反向代理
- dockerfile和镜像管理
- 动作制作docker镜像


# 咨询报名
在线报名地址: https://www.bagevent.com/event/863420
感兴趣可联络思寒同学
微信:seveniruby 手机:15600534760
![](/uploads/photo/2017/d1faea84-a4a5-485e-9666-7fbd60d08259.png!large =300x)

2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version = 1.0.2
sbt.version = 1.0.3
2 changes: 1 addition & 1 deletion src/main/scala/com/testerhome/appcrawler/AppCrawler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ object AppCrawler extends CommonLog {
GA.logLevel = Level.TRACE
log.info(s"verbose=${config.verbose}")
log.info(s"set global log level to ${GA.logLevel}")
RichData.initLog()
XPathUtil.initLog()
}
log.trace("config=")
log.trace(config)
Expand Down
20 changes: 14 additions & 6 deletions src/main/scala/com/testerhome/appcrawler/Crawler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class Crawler extends CommonLog {
//driver.manage().logs().getAvailableLogTypes().toArray.foreach(log.info)
//设定结果目录
runStartupScript()
println("append current app name to appWhiteList")
conf.appWhiteList.append(appNameRecord.last().toString)

if(conf.testcase!=null){
Expand Down Expand Up @@ -218,6 +219,8 @@ class Crawler extends CommonLog {
log.info("set app to null to restart appium")
conf.capability ++= Map("app"->"")
setupAppium()
//todo: 采用轮询
Thread.sleep(8000)
refreshPage()
doElementAction(URIElement(s"${currentUrl}", "", "", "",
s"restart-${store.clickedElementsList.size}"), "")
Expand Down Expand Up @@ -351,8 +354,11 @@ class Crawler extends CommonLog {
}

def needBackApp(): Boolean = {
log.trace(conf.appWhiteList)
log.trace(appNameRecord.record)

//跳到了其他app. 排除点一次就没有的弹框
if (conf.appWhiteList.forall(appNameRecord.last().toString.matches(_)==false) && appNameRecord.last(2).distinct.size>1) {
if (conf.appWhiteList.forall(appNameRecord.last().toString.matches(_)==false)) {
log.warn(s"not in app white list ${conf.appWhiteList}")
log.warn(s"jump to other app appName=${appNameRecord.last()} lastAppName=${appNameRecord.pre()}")
setElementAction("backApp")
Expand Down Expand Up @@ -457,7 +463,7 @@ class Crawler extends CommonLog {
}

//高度小就跳过
if(height<50 && width<50){
if(height<30 && width<30) {
log.info(bounds)
log.info(driver.screenHeight)
log.info("small")
Expand Down Expand Up @@ -694,10 +700,10 @@ class Crawler extends CommonLog {
allElements.foreach(log.debug)

allElements = allElements.filter(!store.isSkiped(_))
log.info(s"fresh elements size=${allElements.length}")
log.info(s"all - skiped fresh elements size=${allElements.length}")
//记录未被点击的元素
allElements.foreach(e => {
log.debug(e)
log.trace(e)
store.saveElement(e)
})
allElements
Expand Down Expand Up @@ -973,7 +979,9 @@ class Crawler extends CommonLog {
back()
}
case "backApp" => {
if (conf.defaultBackAction.size > 0) {
driver.launchApp()
/*if (conf.defaultBackAction.size > 0) {
log.trace(conf.defaultBackAction)
conf.defaultBackAction.foreach(Runtimes.eval)
} else {
driver.backApp()
Expand All @@ -982,7 +990,7 @@ class Crawler extends CommonLog {
driver.launchApp()
}
}
}*/
}
case "monkey" => {
driver.event(element.name.toInt)
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/com/testerhome/appcrawler/CrawlerConf.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CrawlerConf {
var reportTitle = ""
var screenshotTimeout = 20
var currentDriver = "Android"
var tagLimitMax = 6
var tagLimitMax = 3
var tagLimit = ListBuffer[Map[String, Any]]()
//var tagLimit=scala.collection.mutable.Map[String, Int]()
var showCancel = false
Expand Down Expand Up @@ -98,10 +98,10 @@ class CrawlerConf {
var testcase=TestCase(
name="TesterHome AppCrawler",
steps = List(
Step(given = null, when = null, xpath="//*", action = "driver.swipe(0.9, 0,5, 0.1, 0.5)", then=null),
Step(given = null, when = null, xpath="//*", action = "driver.swipe(0.9, 0,5, 0.1, 0.5)", then=null),
Step(given = null, when = null, xpath="//*", action = "driver.swipe(0.9, 0,5, 0.1, 0.5)", then=null),
Step(given = null, when = null, xpath="//*", action = "driver.swipe(0.9, 0,5, 0.1, 0.5)", then=null)
Step(given = null, when = null, xpath="//*", action = "driver.swipe(0.9, 0.5, 0.1, 0.5)", then=null),
Step(given = null, when = null, xpath="//*", action = "driver.swipe(0.9, 0.5, 0.1, 0.5)", then=null),
Step(given = null, when = null, xpath="//*", action = "driver.swipe(0.9, 0.5, 0.1, 0.5)", then=null),
Step(given = null, when = null, xpath="//*", action = "driver.swipe(0.9, 0.5, 0.1, 0.5)", then=null)
)
)

Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/com/testerhome/appcrawler/DataRecord.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import scala.collection.mutable.ListBuffer
* Created by seveniruby on 16/8/25.
*/
class DataRecord extends CommonLog {
private val record=ListBuffer[(Long, Any)]()
val record=ListBuffer[(Long, Any)]()
//todo: 暂时只用2个就足够了
private val size=10
def append(any: Any): Unit ={
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/com/testerhome/appcrawler/DiffSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class DiffSuite extends FunSuite with Matchers with CommonLog{
case Some(elementInfo) if elementInfo.action==ElementStatus.Clicked && elementInfo.resDom.nonEmpty => {
log.debug(elementInfo)
log.debug(elementInfo.resDom)
DiffSuite.range.map(RichData.getListFromXPath(_, RichData.toDocument(elementInfo.resDom)))
DiffSuite.range.map(XPathUtil.getListFromXPath(_, XPathUtil.toDocument(elementInfo.resDom)))
.flatten.map(m=>{
val ele=URIElement(m, key)
ele.loc->ele
Expand All @@ -43,7 +43,7 @@ class DiffSuite extends FunSuite with Matchers with CommonLog{
val candidateElements=DiffSuite.candidateStore.get(key) match {
//todo: 老版本点击过, 新版本没点击过, 没有resDom如何做
case Some(elementInfo) if elementInfo.action==ElementStatus.Clicked && elementInfo.resDom.nonEmpty => {
DiffSuite.range.map(RichData.getListFromXPath(_, RichData.toDocument(elementInfo.resDom)))
DiffSuite.range.map(XPathUtil.getListFromXPath(_, XPathUtil.toDocument(elementInfo.resDom)))
.flatten.map(m=>{
val ele=URIElement(m, key)
ele.loc->ele
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/com/testerhome/appcrawler/Report.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ trait Report extends CommonLog {
changeTitle()
}

def changeTitle(): Unit ={
def changeTitle(title:String=Report.title): Unit ={
val originTitle="ScalaTest Results"
val indexFile=reportPath+"/index.html"
val newContent=Source.fromFile(indexFile).mkString.replace(originTitle, Report.title)
val newContent=Source.fromFile(indexFile).mkString.replace(originTitle, title)
scala.reflect.io.File(indexFile).writeAll(newContent)
}

Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/com/testerhome/appcrawler/Template.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ class Template {
val page=Source.fromURL(s"${url}/source/xml").mkString
val xml=DataObject.fromJson[Map[String, String]](page).getOrElse("value", "")
.asInstanceOf[Map[String, String]].getOrElse("tree", "")
val doc=RichData.toDocument(xml)
val doc=XPathUtil.toDocument(xml)
elements("Demo")=ListBuffer[Map[String, Any]]()
elements("Demo")++=RichData.getListFromXPath("//*[]", doc)
elements("Demo")++=XPathUtil.getListFromXPath("//*[]", doc)

}
def read(path:String): Unit = {
Expand All @@ -35,12 +35,12 @@ class Template {
val reqDom = s._2.reqDom
val url = s._2.element.url
if (reqDom.size != 0) {
val doc = RichData.toDocument(reqDom)
val doc = XPathUtil.toDocument(reqDom)

if (elements.contains(url) == false) {
elements.put(url, ListBuffer[Map[String, Any]]())
}
elements(url) ++= RichData.getListFromXPath("//*", doc)
elements(url) ++= XPathUtil.getListFromXPath("//*", doc)
val tagsLimit=List("Image", "Button", "Text")
elements(url) = elements(url)
.filter(_.getOrElse("visible", "true")=="true")
Expand Down
14 changes: 7 additions & 7 deletions src/main/scala/com/testerhome/appcrawler/TemplateTestCase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,21 @@ class TemplateTestCase extends FunSuite with BeforeAndAfterAllConfigMap with Mat
""".stripMargin
)
*/
val req = RichData.toDocument(ele.reqDom)
val res = RichData.toDocument(ele.resDom)
val req = XPathUtil.toDocument(ele.reqDom)
val res = XPathUtil.toDocument(ele.resDom)
log.debug(ele.reqDom)
AppCrawler.crawler.conf.asserts.foreach(assert => {
val given = assert.getOrElse("given", List[String]()).asInstanceOf[List[String]]
log.info(given.map(g => RichData.getListFromXPath(g, req).size))
if (given.forall(g => RichData.getListFromXPath(g, req).size > 0) == true) {
log.info(given.map(g => XPathUtil.getListFromXPath(g, req).size))
if (given.forall(g => XPathUtil.getListFromXPath(g, req).size > 0) == true) {
log.info(s"asserts match")
val existAsserts = assert.getOrElse("then", List[String]()).asInstanceOf[List[String]]
val cp = new scalatest.Checkpoints.Checkpoint
existAsserts.foreach(existAssert => {
log.debug(existAssert)
cp {
withClue(s"${existAssert} 不存在\n") {
RichData.getListFromXPath(existAssert, res).size should be > 0
XPathUtil.getListFromXPath(existAssert, res).size should be > 0
}
}
})
Expand All @@ -85,7 +85,7 @@ class TemplateTestCase extends FunSuite with BeforeAndAfterAllConfigMap with Mat
})

AppCrawler.crawler.conf.testcase.steps.foreach(step => {
if (RichData.getListFromXPath(step.when.xpath, req)
if (XPathUtil.getListFromXPath(step.when.xpath, req)
.map(_.getOrElse("xpath", ""))
.headOption == Some(ele.element.loc)
) {
Expand All @@ -97,7 +97,7 @@ class TemplateTestCase extends FunSuite with BeforeAndAfterAllConfigMap with Mat
log.debug(existAssert)
cp {
withClue(s"${existAssert} 不存在\n") {
RichData.getListFromXPath(existAssert, res).size should be > 0
XPathUtil.getListFromXPath(existAssert, res).size should be > 0
}
}
})
Expand Down
5 changes: 4 additions & 1 deletion src/main/scala/com/testerhome/appcrawler/URIElement.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ case class URIElement(url: String="", tag: String="", id: String="", name: Strin
def toFileName(): String ={
//url_[parent id]-tag-id
s"${url}_${"\"([^/0-9][^\" =]*)\"".r.findAllMatchIn(loc).map(_.subgroups).toList.flatten.
map(_.split("/").lastOption.getOrElse("")).mkString("-")}".replaceAll("[\\\\/?\"*<>\\|\n ]", ".").take(200)
map(_.split("/").lastOption.getOrElse("")).mkString("-")}"
.replaceAll("[\\\\/?\"*<>\\|\n ]", ".")
.replace("android.widget.", "")
.take(100)
}

/**
Expand Down
Loading

0 comments on commit 9c9cd0f

Please sign in to comment.