热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android目录遍历工具|AppCrawler自动化测试进阶(第二部分):个性化配置详解

终于迎来了“足不出户也能为社会贡献力量”的时刻,但有追求的测试工程师绝不会让自己的生活变得乏味。与其在家消磨时光,不如利用这段时间深入研究和提升自己的技术能力,特别是对AppCrawler自动化测试工具的个性化配置进行详细探索。这不仅能够提高测试效率,还能为项目带来更多的价值。

终于到了“啥也不干躺在家就能给社会做贡献”的时候,但有梦想的测试人从不会让自己的生活变得无聊!与其宅在家里数瓜子壳,还不如利用整块时间提升测试开发技能!

1fcdf6c0a081f096d4fe2c23efbf4612.png

定制化配置

自动遍历测试技术以及工具该如何选择和快速入门?经过对比和需求,最终选择测试架构师思寒大佬的 AppCrawler 作为自动遍历测试的工具。以下就分享 AppCrawler 自动遍历测试的一些最佳实践经验。

模板文件生成

运行命令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 --demo2019-12-01 21:33:35 INFO [AppCrawler$.86.main]----------------AppCrawler 2.4.0 [霍格沃兹测试学院特别纪念版]Appium 1.8.1 Java8 testedapp爬虫, 用于自动遍历测试. 支持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 47232019-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 = 201912012133352019-12-01 21:33:36 INFO [AppCrawler$.286.parseParams] you can read /Users/qinzhen/Documents/TestDev/AppCrawler/demo.yml for demo#查看配置文件已生成$ lsappcrawler-2.4.0-jar-with-dependencies.jardemo.yml

  • 打开配置文件demo.yaml如下:

---pluginList: []saveScreen: truereportTitle: ""resultDir: "20191201213335"waitLoading: 500waitLaunch: 6000showCancel: truemaxTime: 10800maxDepth: 10capability: 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: 0selectedList:- given: [] when: null then: [] xpath: "//*[contains(name(), &#39;Button&#39;)]" action: null actions: [] times: 0- given: [] when: null then: [] xpath: "//*[contains(name(), &#39;Text&#39;) and &#64;clickable&#61;&#39;true&#39; and string-length(&#64;text)<10]" action: null actions: [] times: 0- given: [] when: null then: [] xpath: "//*[&#64;clickable&#61;&#39;true&#39;]/*[contains(name(), &#39;Text&#39;) and string-length(&#64;text)<10]" action: null actions: [] times: 0- given: [] when: null then: [] xpath: "//*[contains(name(), &#39;Image&#39;) and &#64;clickable&#61;&#39;true&#39;]" action: null actions: [] times: 0- given: [] when: null then: [] xpath: "//*[&#64;clickable&#61;&#39;true&#39;]/*[contains(name(), &#39;Image&#39;)]" action: null actions: [] times: 0- given: [] when: null then: [] xpath: "//*[contains(name(), &#39;Image&#39;) and &#64;name!&#61;&#39;&#39;]" action: null actions: [] times: 0- given: [] when: null then: [] xpath: "//*[contains(name(), &#39;Text&#39;) and &#64;name!&#61;&#39;&#39; and string-length(&#64;label)<10]" action: null actions: [] times: 0firstList: []lastList:- given: [] when: null then: [] xpath: "//*[&#64;selected&#61;&#39;true&#39;]/..//*" action: null actions: [] times: 0- given: [] when: null then: [] xpath: "//*[&#64;selected&#61;&#39;true&#39;]/../..//*" action: null actions: [] times: 0backButton:- given: [] when: null then: [] xpath: "Navigate up" action: null actions: [] times: 0triggerActions:- given: [] when: null then: [] xpath: "share_comment_guide_btn" action: null actions: [] times: 0xpathAttributes:- "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: 0beforeRestart: []beforeElement:- given: [] when: null then: [] xpath: "/*" action: "Thread.sleep(500)" actions: [] times: 0afterElement: []afterPage: []afterPageMax: 2tagLimitMax: 2tagLimit:- 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: 1000assertGlobal: []

执行参数

同样&#xff0c;还是以雪球 App 为例&#xff0c;以实际操作运行来解释配置文件中各个参数的含义和用法

  • 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

这里再介绍两个很有趣也很有用的参数&#xff1a;

dontStopAppOnReset: true ;这个参数允许我们在某个页面继续执行遍历&#xff0c;比如我们希望App先进入到某个页面后再进行遍历&#xff0c;或者当一个session结束后继续下一个session的时候我们希望不要杀死App重新执行&#xff0c;而是继续上一次结束的页面开始执行

ignoreUnimportantViews: 这个参数设置为true的时候可以忽略不重要的view&#xff0c;加速pageSource的加载&#xff0c;加快测试速度

  • testcase: 用于启动APP后的基础测试用例
12af459ced55406f30a835b72206c724.png

允许我们以 given、when、then 的形式指定操作&#xff0c;如果学习过 Java 的接口自动化框架 rest-assured 话可以很容易理解这三个参数表达的含义&#xff1a;

  • given : 所有的先决条件&#xff0c;给定一个条件&#xff0c;只有条件成立的时候才完成后面的操作(实际用的较少)
  • when : 先决条件成立后的行为&#xff0c;对什么事件做什么事情
  • then : 断言集合&#xff0c;事件结束后对结果断言

具体写法如下&#xff1a;

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(&#64;text, &#39;美股&#39;)]

ebe3347805b75b54a784682f370433c3.png

另外实际使用中我们会经常使用简写形态

  • 直接使用 xpath 对应 when 里面的 xpath
  • 直接使用 action 对应 when 里面的 action 具体写法如下&#xff1a;

- xpath: 自选 action: click then: - //*[contains(&#64;text, &#39;美股&#39;)]

c0a36a4d4ffcb783b503556ad7fe14a1.png

注&#xff1a;定位模式除了可以使用 xpath 之外还可以使用正则和包含关系&#xff0c;只不过经常使用的是 xpath&#xff0c;也更为严谨&#xff1b;

  • 正则&#xff1a;使用^开头的就认定为正则&#xff0c;^确定$&#xff0c;^.*输入密码
  • 包含&#xff1a;可以使用元素其中包含的内容进行定位; 密码&#xff0c;输入&#xff0c;请

这里以雪球首页搜索框输入 alibaba 的简单场景举例&#xff0c;在搜索前还需要处理掉升级弹框&#xff0c;修改完成如下:

testcase: name: "XueQiuTestDemo AppCrawler" steps: - { xpath: "//*[contains(&#64;resource-id,&#39;image_cancel&#39;)]", action: click } - xpath: home_search action: click - xpath: search_input_text action: alibaba

如上的 testcase 写法还要多说几句&#xff1a;

  • 也可以使用 {} 将需要执行的事件包裹起来&#xff0c;元素定位符和操作 action 时间用逗号隔开
  • {} 内若使用 xpath 表达式的话需要加双引号
  • xpath 中直接写 id 或 text 文本信息&#xff0c;就会默认使用包含去查找
  • 需要点击的事件要明确指明 click&#xff0c;某则会报错&#xff1b;虽然思寒说过默认的 action 就是 click &#xff0c;但是经过实测发现在 2.4.0 版本上必须指明 action&#xff1a;click ; 很可能是思寒本地使用的内部版本经过了优化更新还未来得及开源到 GitHub上。

运行效果&#xff1a;

format,png

selectedList: 遍历范围设定

这里如果想设置让其点击所有可点击的TextView和ImageView控件,修改完成如下:

selectedList:- xpath: //android.widget.ImageView[&#64;clickable&#61;&#39;true&#39;]- xpath: //*[&#64;clickable&#61;&#39;true&#39; and contains(&#64;class,"Text")]

  • firstList: 优先被点击
  • lastList:最后执行 设置其最后才执行"确定"按钮,修改完成如下&#xff1a;

lastList:- { xpath: text_yes, action: click }

  • backButton: 当所有元素都被点击后默认后退控件定位
  • blackList&#xff1a;黑名单
  • triggerAction: 特定条件出发执行动作的设置;设置遇到重置密码输入框时输入123456abc两次,修改完成如下:

triggerActions:- { xpath: android.widget.EditText, action: 123456abc, times: 2 }

  • tagLimitMax: 全局设置,同类型的最多点击的次数;这里设置为2次

tagLimitMax: 2

  • tagLimit: 自定义控件类型的点击次数,这里设置对于ListView类型的只点击一次; 修改完成如下 &#xff1a;

- { xpath: "//*[contains(&#64;class, &#39;List&#39;)]//*", times: 1 }

  • maxDepth: 遍历的最大深度

assertGlobal&#xff1a;设置一个全局断言&#xff0c;例如可设置断言在当前App&#xff0c;如果包名不符合&#xff0c;就可能发生了崩溃&#xff0c;便会报错

注&#xff1a;执行参数比配置文件优先级高

到这里&#xff0c;appcrawler的基本语法和参数含义大致介绍了一遍&#xff0c;后面就是如何结合实际进行使用了。

(文章来源于霍格沃兹测试学院)



推荐阅读
  • 本文总结了一次针对大厂Java研发岗位的面试经历,探讨了面试中常见的问题及其背后的原因,并分享了一些实用的面试准备资料。 ... [详细]
  • 流处理中的计数挑战与解决方案
    本文探讨了在流处理中进行计数的各种技术和挑战,并基于作者在2016年圣何塞举行的Hadoop World大会上的演讲进行了深入分析。文章不仅介绍了传统批处理和Lambda架构的局限性,还详细探讨了流处理架构的优势及其在现代大数据应用中的重要作用。 ... [详细]
  • 本文探讨了一种统一的语义数据模型,旨在支持物联网、建筑及企业环境下的数据转换。该模型强调简洁性和可扩展性,以促进不同行业间的插件化和互操作性。对于智能硬件开发者而言,这一模型提供了重要的参考价值。 ... [详细]
  • 我正在使用 Ruby on Rails 构建个人网站。总体而言,RoR 是一个非常出色的工具,它提供了丰富的功能和灵活性,使得创建自定义页面变得既高效又便捷。通过利用其强大的框架和模块化设计,我可以轻松实现复杂的功能,同时保持代码的整洁和可维护性。此外,Rails 的社区支持也非常强大,为开发过程中遇到的问题提供了丰富的资源和解决方案。 ... [详细]
  • 本文推荐了六款高效的Java Web应用开发工具,并详细介绍了它们的实用功能。其中,分布式敏捷开发系统架构“zheng”项目,基于Spring、Spring MVC和MyBatis技术栈,提供了完整的分布式敏捷开发解决方案,支持快速构建高性能的企业级应用。此外,该工具还集成了多种中间件和服务,进一步提升了开发效率和系统的可维护性。 ... [详细]
  • 作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ... [详细]
  • 我的读书清单(持续更新)201705311.《一千零一夜》2006(四五年级)2.《中华上下五千年》2008(初一)3.《鲁滨孙漂流记》2008(初二)4.《钢铁是怎样炼成的》20 ... [详细]
  • 探讨Redis的最佳应用场景
    本文将深入探讨Redis在不同场景下的最佳应用,包括其优势和适用范围。 ... [详细]
  • 在ElasticStack日志监控系统中,Logstash编码插件自5.0版本起进行了重大改进。插件被独立拆分为gem包,每个插件可以单独进行更新和维护,无需依赖Logstash的整体升级。这不仅提高了系统的灵活性和可维护性,还简化了插件的管理和部署过程。本文将详细介绍这些编码插件的功能、配置方法,并通过实际生产环境中的应用案例,展示其在日志处理和监控中的高效性和可靠性。 ... [详细]
  • 技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告
    技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告 ... [详细]
  • 在 Rails 应用中使用 Delayed Job 时,自定义作业类的最佳存储位置是 `app/jobs` 目录。这不仅符合 Rails 的约定,还能确保代码结构清晰、易于管理和维护。每个自定义作业类应包含具体的任务逻辑,并可以通过 `perform` 方法来执行。此外,建议为每个作业类编写单元测试,以确保其功能的正确性和可靠性。 ... [详细]
  • 在数据库设计中,谨慎使用外键至关重要。本文探讨了九个关键原因,包括数据完整性的维护、性能优化、系统复杂性的管理、数据迁移的灵活性以及对外部系统的依赖性控制。通过深入分析这些因素,可以帮助开发人员和架构师做出更明智的设计决策,确保数据库系统的高效与稳定。 ... [详细]
  • 利用Python与Android进行高效移动应用开发
    通过结合Python和Android,可以实现高效的移动应用开发。首先,需要安装Scripting Layer for Android (SL4A),这是一个开源项目,旨在为Android系统提供脚本语言支持。SL4A不仅简化了开发流程,还允许开发者使用Python等高级语言编写脚本,从而提高开发效率和代码可维护性。此外,SL4A还支持多种其他脚本语言,进一步扩展了其应用范围。通过这种方式,开发者可以快速构建功能丰富的移动应用,同时保持较高的灵活性和可扩展性。 ... [详细]
  • 本文深入探讨了使用Puppet进行软件包分发与管理的方法。首先介绍了fpm这一跨平台的软件包制作工具,其简便的操作流程使得软件包的创建变得轻松快捷。fpm的项目地址为:https://github.com/jordansissel/fpm。通过结合Puppet和fpm,可以实现高效、可靠的软件包管理和部署。 ... [详细]
  • 掌握PHP编程必备知识与技巧——全面教程在当今的PHP开发中,了解并运用最新的技术和最佳实践至关重要。本教程将详细介绍PHP编程的核心知识与实用技巧。首先,确保你正在使用PHP 5.3或更高版本,最好是最新版本,以充分利用其性能优化和新特性。此外,我们还将探讨代码结构、安全性和性能优化等方面的内容,帮助你成为一名更高效的PHP开发者。 ... [详细]
author-avatar
如果-不曾开始_632
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有