1、前情回顾
在上一篇中已经初步的认识了自动遍历测试技术以及工具的选择和快如入门,对过对比和需求,最终选择以testerhome
社区联合创始人,前阿里、百度和雪球的测试架构师思寒大佬的AppCrawler
作为自动遍历测试的工具,详细回顾可参考博客:
初探自动遍历测试工具-AppCrawler
2、定制化配置
2.1模板文件生成
- 运行命令
java -jar appcrawler-2.4.0-jar-with-dependencies.jar --demo
,会在当前目录下生成一个demo.yml
文件,这个文件就是我们进行定制化的配置文件模板:#执行命令生成demo.yaml模板配置文件 $ java -jar appcrawler-2.4.0-jar-with-dependencies.jar --demo 2019-12-01 21:33:35 INFO [AppCrawler$.86.main] ---------------- AppCrawler 2.4.0 [霍格沃兹测试学院特别纪念版] Appium 1.8.1 Java8 tested app爬虫, 用于自动遍历测试. 支持Android和iOS, 支持真机和模拟器 项目地址: https://github.com/seveniruby/AppCrawler 移动测试技术交流: https://testerhome.com 联络作者: seveniruby@testerhome.com (思寒) 致谢: 晓光 泉龙 杨榕 恒温 mikezhou yaming116 沐木 -------------------------------- 2019-12-01 21:33:35 INFO [AppCrawler$.223.parseParams] use default appium address 4723 2019-12-01 21:33:35 INFO [AppCrawler$.230.parseParams] appium address = Some(http://127.0.0.1:4723/wd/hub) 2019-12-01 21:33:35 INFO [AppCrawler$.242.parseParams] result directory = 20191201213335 2019-12-01 21:33:36 INFO [AppCrawler$.286.parseParams] you can read /Users/qinzhen/Documents/TestDev/AppCrawler/demo.yml for demo #查看配置文件已生成 $ ls appcrawler-2.4.0-jar-with-dependencies.jar demo.yml
- 打开配置文件
demo.yaml
如下:--- pluginList: [] saveScreen: true reportTitle: "" resultDir: "20191201213335" waitLoading: 500 waitLaunch: 6000 showCancel: true maxTime: 10800 maxDepth: 10 capability: noReset: "true" fullReset: "false" appium: "http://127.0.0.1:4723/wd/hub" testcase: name: "TesterHome AppCrawler" steps: - given: [] when: null then: [] xpath: "/*" action: "Thread.sleep(5000)" actions: [] times: 0 selectedList: - given: [] when: null then: [] xpath: "//*[contains(name(), 'Button')]" action: null actions: [] times: 0 - given: [] when: null then: [] xpath: "//*[contains(name(), 'Text') and @clickable='true' and string-length(@text)<10]" action: null actions: [] times: 0 - given: [] when: null then: [] xpath: "//*[@clickable='true']/*[contains(name(), 'Text') and string-length(@text)<10]" action: null actions: [] times: 0 - given: [] when: null then: [] xpath: "//*[contains(name(), 'Image') and @clickable='true']" action: null actions: [] times: 0 - given: [] when: null then: [] xpath: "//*[@clickable='true']/*[contains(name(), 'Image')]" action: null actions: [] times: 0 - given: [] when: null then: [] xpath: "//*[contains(name(), 'Image') and @name!='']" action: null actions: [] times: 0 - given: [] when: null then: [] xpath: "//*[contains(name(), 'Text') and @name!='' and string-length(@label)<10]" action: null actions: [] times: 0 firstList: [] lastList: - given: [] when: null then: [] xpath: "//*[@selected='true']/..//*" action: null actions: [] times: 0 - given: [] when: null then: [] xpath: "//*[@selected='true']/../..//*" action: null actions: [] times: 0 backButton: - given: [] when: null then: [] xpath: "Navigate up" action: null actions: [] times: 0 triggerActions: - 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: []
2.2 执行参数
同样,还是以雪球App为例,以实际操作运行来解释配置文件中各个参数的含义和用法
-
capability设置: 与appium完全一致,但要注意这里默认有
noReset: "true"
和appium: "http://127.0.0.1:4723/wd/hub"
属性,配置完成如下capability: noReset: "false" fullReset: "false" appium: "http://127.0.0.1:4723/wd/hub" appPackage: com.xueqiu.androi appActivity: .view.WelcomeActivityAlias automationName: uiautomator2 autoGrantPermissions: true
这里再介绍两个很有趣也很有用的参数:
dontStopAppOnReset: true
;这个参数允许我们在某个页面继续执行遍历,比如我们希望App先进入到某个页面后再进行遍历,或者当一个session结束后继续下一个session的时候我们希望不要杀死App重新执行,而是继续上一次结束的页面开始执行
ignoreUnimportantViews
: 这个参数设置为true的时候可以忽略不重要的view,加速pageSource的加载,加快测试速度 -
testcase: 用于启动APP后的基础测试用例 完整形态: 允许我们以
given
、when
、then
的形式指定操作,如果学习过Java的接口自动化框架rest-assured
话可以很容易理解这三个参数表达的含义:- given: 所有的先决条件,给定一个条件,只有条件成立的时候才完成后面的操作(实际用的较少)
- when: 先决条件成立后的行为,对什么事件做什么事情
- then: 断言集合,事件结束后对结果断言 具体写法如下:
testcase: name: "TesterHome AppCrawler" steps: - when: xpath: //* action: driver.swipe(0.5, 0.8, 0.5, 0.2) - when: xpath: //* action: driver.swipe(0.5, 0.2, 0.5, 0.8) then: - //*[contains(@text, '美股')]
简写形态: 另外实际使用中我们会经常使用简写形态
- 直接使用
xpath
对应when
里面的xpath
- 直接使用
action
对应when
里面的action
具体写法如下:
- xpath: 自选 action: click then: - //*[contains(@text, '美股')]
- action的动作支持
""
:只是截图记录back
:后退backApp
:回退到当前的App,默认等价于back行为 可定制monkey
:随机事件xxx()
执行代码:- Thread.sleep(1000)
- driver.swipe(0.9,0.8,0.9,0.5)
click
:点击事件longTap
:长按- 除以上所有行为外均视为输入行为
注:定位模式除了可以使用
xpath
之外还可以使用正则和包含关系,只不过经常使用的是xpath
,也更为严谨;- 正则:使用
^
开头的就认定为正则,^确定$
,^.*输入密码
- 包含:可以使用元素其中包含的内容进行定位;
密码
,输入
,请
这里以雪球首页搜索框输入alibaba的简单场景举例,在搜索前还需要处理掉升级弹框,修改完成如下:
testcase: name: "XueQiuTestDemo AppCrawler" steps: - { xpath: "//*[contains(@resource-id,'image_cancel')]", action: click } - xpath: home_search action: click - xpath: search_input_text action: alibaba
如上的testcase写法还要多说几句:
- 也可以使用
{}
将需要执行的事件包裹起来,元素定位符和操作action时间用逗号隔开 {}
内若使用xpath表达式的话需要加双引号- xpath中直接写
id
或text
文本信息,就会默认使用包含去查找 - 需要点击的事件要明确指明
click
,某则会报错;虽然思寒说过默认的action
就是click
,但是经过实测发现在2.4.0版本上必须指明action:click
;很可能是思寒本地使用的内部版本经过了优化更新还未来得及开源到GitHub上
运行效果
-
selectedList: 遍历范围设定 这里如果想设置让其点击所有可点击的
TextView
和ImageView
控件,修改完成如下:selectedList: - xpath: //android.widget.ImageView[@clickable='true'] - xpath: //*[@clickable='true' and contains(@class,"Text")]
-
firstList: 优先被点击
-
lastList:最后执行 设置其最后才执行"确定"按钮,修改完成如下:
lastList: - { xpath: text_yes, action: click }
-
backButton: 当所有元素都被点击后默认后退控件定位
-
blackList:黑名单
-
triggerAction: 特定条件出发执行动作的设置;设置遇到重置密码输入框时输入123456abc两次,修改完成如下:
triggerActions: - { xpath: android.widget.EditText, action: 123456abc, times: 2 }
-
tagLimitMax: 全局设置,同类型的最多点击的次数;这里设置为2次
tagLimitMax: 2
-
tagLimit: 自定义控件类型的点击次数,这里设置对于
ListView
类型的只点击一次; 修改完成如下- { xpath: "//*[contains(@class, 'List')]//*", times: 1 }
-
maxDepth: 遍历的最大深度
-
assertGlobal:设置一个全局断言,例如可设置断言在当前App,如果包名不符合,就可能发生了崩溃,便会报错
注:执行参数比配置文件优先级高
3、写在最后
到这里,appcrawler的基本语法和参数含义大致介绍了一遍,后面就是如何结合实际进行使用了,具体可参考另一篇: 以AppCrawler的配置文件完成定制化的自动遍历测试(实操)-02