利器 | AppCrawler 自动遍历测试实践(三):动手实操与常见问题汇总

简介: 利器 | AppCrawler 自动遍历测试实践(三):动手实操与常见问题汇总



上两篇文章介绍了自动遍历的测试需求、工具选择和 AppCrawler 的环境安装、启动及配置文件字段基本含义,这里将以实际案例更加细致的说明配置文件的用法和一些特殊场景的处理。

下面我们继续之前的例子,在雪球搜索框输入搜索内容后的页面开始:

  • testcase:设置测试用例,输入 alibaba 后,点选"阿里巴巴"

yaml 写法如下:

testcase:
  name: "XueQiuTestDemo AppCrawler"
  steps:
  - { xpath: "//*[contains(@resource-id,'image_cancel')]", action: click }
  - xpath: home_search
    action: click
  - xpath: search_input_text
    action: alibaba
  - { xpath: 阿里巴巴, action: click }
  • selectedList:遍历范围设定
  • 接上一步点选"阿里巴巴"后到达如下界面:

我们先看demo配置文件中的原始写法,如下:

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

原始文件中将所有可点击的控件类型都包括了进去,再加上了部分 text 长度的限制 现在我们按照自己平常的简便写法重新编写,先设置所有 clickable 等于 true 的控件进行点击:

selectedList:
 - { xpath: "//*[@clickable='true']", action: click }
  • blackList:黑名单,将不想要被点击的元素加入黑名单中
  • 配置文件原始写法如下,表示将带有2位数字的排除在外,可能是App中包含了很对关于股价展示的,不需要挨个点击:
blackList:
- given: []
  when: null
  then: []
  xpath: ".*[0-9]{2}.*"
  action: null
  actions: []
  times: 0

我们现在希望不要点击到叉号和取消按钮,否则会跳出此页面,那么就可以把其加入黑名单中,如下:

blackList:
 - xpath: ".*[0-9]{2}.*"
 - xpath: //*[@resource-id='action_delete_text']
 - xpath: //*[@resource-id='action_close']
  • firstList: 优先被遍历
  • 这里我们设置让text包含"股票"的优先遍历
firstList:
 - { xpath: "//*[contains(@text,'股票')]", action: click }
  • lastList:最后被点击
  • 在页面中有很多标签页(例如综合、股票、用户、组合):

每个标签页下面对应着很多控件需要被操作,可是在当前页面下的控件未被遍历完的时候就有可能会点击到其他标签页中了,我们希望的是在一个标签页下完全遍历结束后最后再点击标签控件,这个就可以借助lastList来完成,让元素在点进标签页后的内容为最后遍历

lastList:
 - { xpath: "//*[contains(@resource-id,'ti_tab_indicator')]//*", action: click }
  • backButton: 当所有元素都被点击后默认后退控件定位
  • AppCrawler是不知道后退按钮是哪一个的,这个可能会造成的一种情况是,当我们进入一个页面时,还没有对这个页面完全遍历就点到了后退按钮,这样就会造成测试不充分

因此我们可以给它设置一个默认的后退按钮,使所有事件完成后再 back

backButton:
 - { xpath: "//*[contains(@resource-id,'action_back')]", action: click }
  • maxDepth: 遍历的最大深度
  • 有时候我们的页面层次可能很深,每次遍历测试的需求可能不同,有时候可能需要在短时间内测试主要常用界面的功能,有时候可能需要全面的测试,所以测试的深度就不相同,我们可以依靠 maxDepth 来进行需求定制,这里以遍历 2 层深度为例:
maxDepth: 2
  • findBy:定位方式的选择
  • findBy 可以设置定位方式,有 default、android、id、xpth 方式可选,默认状态会自动判断是否是要 Android 定位或者 iOS 定位。当我们的定位很精准的时候,用默认的 default 速度会快一点;若是定位符写的不是很精准,在切换到 Android 定位的时候可能找不到,这个时候就可以尝试将其设置为 Xpath方式定位。
findBy: "xpath"
  • defineUrl = ListString:用来确定url的元素定位 xpath,他的 text 会被取出当做 url 因素;就是说如果想要当前的页面布局与某个控件之间有层级关系,给定一个标记控件,以此来区分不同的界面(语言的描述怎么样都有点晦涩,还是结合下面的示例来理解吧。。。)

有时候我们会遇见这种情况:设置了 clickable 未 true 的控件都被遍历,可是运行时发现很多控件都没有被遍历到,一般这种情况有一下两种原因:

  • 元素属性 clickable 本身就为 false 或者它的父节点等都为 false,这样自然是无法遍历到的。
  • 还有一种情况是同属性的控件在两个tag页面都存在,在其中一个tag页遍历一遍之后,再到下一个tag页中就会默认已经遍历,不会再进行遍历,如下这种:

在“股票”和“用户”tag页中,“加自选”和“关注”控件的clickable及id属性一样。



他们所属的页面属性也一样,所以会被看做是同一个页面下的同一个控件:





如上这种情况肯定不是我们想要的,我们想要它在股票和用户页都分别进行遍历,更好的覆盖测试,那么就要借助于 defineUrl 了;

1)按照上面的介绍,我们首先要找一个标志控件,用来做页面的区分,那么我们首先想到的就是从“股票”和“用户”这两个 tag 标签属性上来找,遗憾的是最终发现这两个控件的属性全都一毛一样:

2)接着我们就必须从 tag 页内部来找标志控件了,我们发现在“股票”和“用户”页中搜索出来的结果名称的 id 是不同的:



3)上面介绍过了 defineUrl 是取的 text 属性值作为标志区分,所以这里取股票页的第一个元素“阿里巴巴”和用户页的第二个元素“阿里巴巴四十大盗”,

具体 yaml 写法如下:

defineUrl: 
- (//*[contains(@resource-id, "stockName")])[1]
- (//*[contains(@resource-id, "user_name")])[2]

缺点:上面的做法虽然解决了页面区分的问题,但是有一个缺点就是我们定义了遍历的深度,然而使用 defineUrl 之后将每个标志符在的页面都视为一个新的 activity,因此遍历深度就会从这里开始重新计算

4)继续解决上述的缺点,我们可以在 clickable 之前指定所属的页面,当判断不在此页面后就会自动跳回

selectedList: 
- { xpath: "//*[@resource-id='com.xueqiu.android:id/ll_search_result']//*[@clickable='true']//*", action: click }

5)另外我们之前在 selectList 中写了 clickable=true, 而 clickable=true 通常只是布局元素,布局元素一般是没有任何属性的,不知道控件里包含什么,这样在截图和生成报告的时候就会造成不精准,截图中的步骤框就很可能选择错误,对我们定位分析问题造成困扰;

所以我们要继续往下找标志符,以 Text 作为定位标志符:

selectedList:
 - { xpath: "//*[@resource-id='com.xueqiu.android:id/ll_search_result']//*[@clickable='true']//*[contains(@class,'Text')]", action: click }

用 Text 作为标志符以后所有的 Text 属性都会遍历一遍,还可以进一步优化,使用id非空作为判定条件,并且通常研发将控件设置 id 的话很可能此控件有关键的作用

selectedList:
 - { xpath: "//*[@resource-id='com.xueqiu.android:id/ll_search_result']//*[@clickable='true']//*[@resource-id!='']", action: click }

6)按照上面的写法又引发了新的问题,就是 id 不为空的时候,我们的 tag 控件无法被选中了,因为 tag 控件的 id 正好为空:


因此我们又需要对 selectedList 进行修改,单独增加一条判定条件用来过滤出 tag 控件;我们注意到它们同属一片有 id 的区域,并且各自自身有 text:

1080×479 70.1 KB

修改后的selectedList如下:

selectedList:
 - { xpath: "//*[@clickable='true']//*[contains(@class,'Text')]", action: click }
 - { xpath: "//*[contains(@resource-id, 'ti_tab_indicator')]//*[contains(@class,'Text')]",
  • tagLimitMax:最大的点击次数
  • 有时候页面中可能会有多个相同类型的控件,这些控件之间可能只是展示的信息不同,其他功能属性都一直,那么为了保证测试效率可以只设置让它被点击少数次或者一次,通过 tagLimitMax 设置即可。
tagLimitMax: 1

缺点:这个设置是一个全局的,一旦设置,那么所有的同类型的控件都只会被点击一次,但是像上个例子中的 4 个tag标签控件虽然是同类型的,但是每一个都需要被点击一次,这样显然就不符合我们的需求了,这个时候就需要 tagLimit 参数了

  • tagLimit:自定义控件类型的点击次数
tagLimit:
 - xpath: //*[contains(@resource-id, 'ti_tab_indicator')]//*[contains(@class,'Text')]
  action: click
  times: 4
  • triggerActions:触发器,特定条件触发执行动作的设置 这个参数是一个非常有用的参数,比如我们可能会遇到如下的情况

  • 广告、升级弹框在测试过程中突然出现
  • 某些动作需要输入
  • 某些动作需要特定次数的操作
  • 这样每次出现弹框都会被处理
  • 测试中途碰到了账号密码输入框需要输入的可以提前在triggerActions中设置
triggerActions:
 - xpath: //*[contains(@resource-id,'image_cancel')]
   action: click
   times: 1
  1. App 运行比较慢,容易超时怎么办?
    答:AppCrawler 默认每次操作时会等待 500ms; 通过 triggeraction 来解决需要等待的条件,xpath 为进度条,action 为 sleep 1s。
  2. tagLimit 会限制同属性但不同层级的元素吗?
    答:tagLimit 限制的是相同的父节点层级,不管属性,是看布局的层级。
  3. 如何防止遍历的时候不小心跳到别的应用?跳到别的应用后怎么回来?
    答:会自动跳转回来的。除非设置了 App 的白名单
  4. 页面需要在当前页不停滑动加载测试
    答:遍历完当前页后用 afterpage 参数设置滑动
  5. firstList 和 lastList 可以写多个表达式吗?他们是如何执行的?
    答:顺序是这样排列的
  6. app 运行比较慢,容易超时怎么办?
    答:AppCrawler 默认每次操作时会等待 500ms;通过 triggeraction 来解决需要等待的条件,xpath 为进度条,action 为 sleep 1s
  7. tagLimit 会限制同属性但不同层级的元素吗?
    答:tagLimit 限制的是相同的父节点层级,不管属性,是看布局的层级
  8. 如何防止遍历的时候不小心跳到别的应用?跳到别的应用后怎么回来?
    答:会自动跳转回来的。除非设置了 App 的白名单
  9. 页面需要在当前页不停滑动加载测试
    答:遍历完当前页后用 afterpage 参数设置滑动
  10. firstList 和 lastList 可以写多个表达式吗?他们是如何执行的?
    答:顺序是这样排列的
firstList[0]
firstList[1]
排除lastList firstList之后剩下的元素
lastList[0]
lastList[1]
backbutton
  1. Appclawer ==>maxDepth:这个层级是如何定义的?
    答:maxDepth 可以从 log 中看到,AppCrawler.log 中有一个 Stack 的输出,里面默认保存的是所有 activity 的栈记录。

Main

Main->UserProfile

Main->UserProfile->Login

Main

maxDepth是判断这个堆栈最长的长度,一旦超过就回退


相关文章
|
1月前
|
测试技术
软件测试的艺术:探索式测试的实践与思考
在软件开发的广阔海洋中,测试是确保航船稳健行驶的关键。本文将带你领略探索式测试的魅力,一种结合创造性思维和严格方法论的测试方式。我们将一起揭开探索式测试的神秘面纱,了解其核心概念、实施步骤和带来的效益。通过实际代码示例,你将学会如何将探索式测试融入日常的软件质量保证流程中,提升测试效率与质量。
|
22天前
|
数据采集 监控 机器人
浅谈网页端IM技术及相关测试方法实践(包括WebSocket性能测试)
最开始转转的客服系统体系如IM、工单以及机器人等都是使用第三方的产品。但第三方产品对于转转的业务,以及客服的效率等都产生了诸多限制,所以我们决定自研替换第三方系统。下面主要分享一下网页端IM技术及相关测试方法,我们先从了解IM系统和WebSocket开始。
40 4
|
24天前
|
人工智能 JavaScript 前端开发
自动化测试框架的演进与实践###
本文深入探讨了自动化测试框架从诞生至今的发展历程,重点分析了当前主流框架的优势与局限性,并结合实际案例,阐述了如何根据项目需求选择合适的自动化测试策略。文章还展望了未来自动化测试领域的技术趋势,为读者提供了宝贵的实践经验和前瞻性思考。 ###
|
22天前
|
测试技术 Python
探索软件测试的深度与广度:从理论到实践
在数字化时代,软件已成为我们生活中不可或缺的一部分。随着技术的不断进步和用户需求的多样化,确保软件质量变得尤为重要。本文将深入浅出地介绍软件测试的核心概念、类型及其在软件开发生命周期中的重要性。我们将通过实际案例,展示如何实施有效的测试策略,并探讨自动化测试的未来趋势,旨在为读者提供一套完整的软件测试知识体系,帮助提升软件质量和开发效率。
|
23天前
|
测试技术 Python
探索软件测试的奥秘:从理论到实践
在软件开发的宇宙中,软件测试犹如一颗璀璨的星辰,指引着质量的方向。本文将带你穿梭于软件测试的理论与实践之间,揭示其内在的逻辑和魅力。从测试的重要性出发,我们将探讨不同类型的测试方法,并通过实际案例分析,深入理解测试用例的设计和应用。最后,我们将通过一个代码示例,展示如何将理论知识转化为实际操作,确保软件质量的同时,也提升你的测试技能。让我们一起踏上这段探索之旅,发现软件测试的无限可能。
|
26天前
|
jenkins 测试技术 持续交付
自动化测试框架的搭建与实践
在软件开发领域,自动化测试是提升开发效率、确保软件质量的关键手段。本文将引导读者理解自动化测试的重要性,并介绍如何搭建一个基本的自动化测试框架。通过具体示例和步骤,我们将探索如何有效实施自动化测试策略,以实现软件开发流程的优化。
54 7
|
25天前
|
测试技术
探索软件测试的奥秘:从理论到实践
本文深入探讨了软件测试的基本概念、重要性、主要类型以及实施策略。通过分析不同测试阶段和相应的测试方法,文章旨在为读者提供一套完整的软件测试知识体系,帮助他们更好地理解和应用测试技术,确保软件产品的质量和可靠性。
48 4
|
29天前
|
机器学习/深度学习 人工智能 自然语言处理
智能化软件测试:AI驱动的自动化测试策略与实践####
本文深入探讨了人工智能(AI)在软件测试领域的创新应用,通过分析AI技术如何优化测试流程、提升测试效率及质量,阐述了智能化软件测试的核心价值。文章首先概述了传统软件测试面临的挑战,随后详细介绍了AI驱动的自动化测试工具与框架,包括自然语言处理(NLP)、机器学习(ML)算法在缺陷预测、测试用例生成及自动化回归测试中的应用实例。最后,文章展望了智能化软件测试的未来发展趋势,强调了持续学习与适应能力对于保持测试策略有效性的重要性。 ####
|
29天前
|
敏捷开发 Devops 测试技术
探索自动化测试之美:从理论到实践
在软件开发的海洋中,自动化测试犹如一座灯塔,指引着项目向着质量和效率的彼岸。本文将扬帆起航,从自动化测试的意义出发,穿越工具选择的海域,停靠在实战演练的岛屿,最终抵达持续集成的港湾。我们将通过一个具体的代码示例,体验自动化测试的魅力,并分享如何将这些实践应用到日常的软件质量保证过程中。
|
28天前
|
存储 算法 C语言
用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容
本文探讨了用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容,旨在为开发者提供全面的指导和灵感。
45 2

热门文章

最新文章