上两篇文章介绍了主动遍历的测试需要、工具抉择和 AppCrawler 的环境装置、启动及配置文件字段根本含意,这里将以理论案例更加粗疏的阐明配置文件的用法和一些非凡场景的解决。实操演示
惯例应用上面咱们持续之前的例子,在雪球搜寻框输出搜寻内容后的页面开始:testcase:设置测试用例,输出 alibaba 后,点选 ” 阿里巴巴 ”
‘ fill=’%23FFFFFF’%3E%3Crect x=’249′ y=’126′ width=’1’ height=’1’%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
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 的控件进行点击:在 Android 中,一个控件如果绑定了用户响应行为的事件,那么 clickable 的属性值就是 trueselectedList: – { xpath: “//[@clickable=’true’]”, action: click }blackList:黑名单,将不想要被点击的元素退出黑名单中 配置文件原始写法如下,示意将带有 2 位数字的排除在外,可能是 App 中蕴含了很对对于股价展现的,不须要挨个点击:blackList:- given: [] when: null then: [] xpath: “.[0-9]{2}.” action: null actions: [] times: 0 咱们当初心愿不要点击到叉号❌和勾销按钮,否则会跳出此页面,那么就能够把其退出黑名单中,如下:
‘ fill=’%23FFFFFF’%3E%3Crect x=’249′ y=’126′ width=’1’ height=’1’%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
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 是不晓得后退按钮是哪一个的,这个可能会造成的一种状况是,当咱们进入一个页面时,还没有对这个页面齐全遍历就点到了后退按钮,这样就会造成测试不充沛
因而咱们能够给它设置一个默认的后退按钮,使所有事件实现后再 backbackButton: – {xpath: “//*[contains(@resource-id,’action_back’)]”, action: click } 这里还要阐明一点,如果 backButton 没有配置,当遍历第一个页面的时候被点击了,再下一个页面的时候,因为曾经被遍历过了,所以就不会优先去遍历这个回退按钮了,对前面的遍历测试没有大的影响,可能就是第一个页面会有遍历不齐全的概率。maxDepth: 遍历的最大深度有时候咱们的页面档次可能很深,每次遍历测试的需要可能不同,有时候可能须要在短时间内测试次要罕用界面的性能,有时候可能须要全面的测试,所以测试的深度就不雷同,咱们能够依附 maxDepth 来进行需要定制,这里以遍历 2 层深度为例:maxDepth: 2 非凡技巧 findBy:定位形式的抉择 findBy 能够设置定位形式,有 default、android、id、xpth 形式可选,默认状态会主动判断是否是要 Android 定位或者 iOS 定位。当咱们的定位很精准的时候,用默认的 default 速度会快一点;若是定位符写的不是很精准,在切换到 Android 定位的时候可能找不到,这个时候就能够尝试将其设置为 Xpath 形式定位。findBy: “xpath”defineUrl = List[String]():用来确定 url 的元素定位 xpath,他的 text 会被取出当做 url 因素;就是说如果想要以后的页面布局与某个控件之间有层级关系,给定一个标记控件,以此来辨别不同的界面 ( 语言的形容怎么样都有点艰涩,还是联合上面的示例来了解吧。。。)有时候咱们会遇见这种状况:设置了 clickable 未 true 的控件都被遍历,可是运行时发现很多控件都没有被遍历到,个别这种状况有一下两种起因:元素属性 clickable 自身就为 false 或者它的父节点等都为 false,这样天然是无奈遍历到的。还有一种状况是同属性的控件在两个 tag 页面都存在,在其中一个 tag 页遍历一遍之后,再到下一个 tag 页中就会默认曾经遍历,不会再进行遍历,如下这种:在“股票”和“用户”tag 页中,“加自选”和“关注”控件的 clickable 及 id 属性一样。
他们所属的页面属性也一样,所以会被看做是同一个页面下的同一个控件:
如上这种状况必定不是咱们想要的,咱们想要它在股票和用户页都别离进行遍历,更好的笼罩测试,那么就要借助于 defineUrl 了;1)依照下面的介绍,咱们首先要找一个标记控件,用来做页面的辨别,那么咱们首先想到的就是从“股票”和“用户”这两个 tag 标签属性上来找,遗憾的是最终发现这两个控件的属性全都一毛一样:
‘ fill=’%23FFFFFF’%3E%3Crect x=’249′ y=’126′ width=’1’ height=’1’%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
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:
批改后的 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: 4triggerActions:触发器,特定条件触发执行动作的设置 这个参数是一个十分有用的参数,比方咱们可能会遇到如下的状况 - 广告、降级弹框在测试过程中忽然呈现 - 某些动作须要输出 - 某些动作须要特定次数的操作而这个时候就轮到 triggerActions 大显神通了,它能够对特定的控件指定特定的动作和次数,在每一次遍历执行前都会先执行一遍 triggerActions,它不像 testcase 是个流模式的,执行完就完结了,triggerActions 会始终随同着执行 - 这样每次呈现弹框都会被解决 - 测试中途碰到了账号密码输入框须要输出的能够提前在 triggerActions 中设置不晓得大家还记得在刚开始运行的时候,因为在已进入主页的时候就会有降级弹框出来,所以那时候我在 testcase 中退出了步骤将其点掉,然而如果在其余页面再次弹出的话就无奈解决,当初以此为例,将其退出 triggerActionstriggerActions: – xpath: //*[contains(@resource-id,’image_cancel’)] action: click times: 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 1s7. tagLimit 会限度同属性但不同层级的元素吗?答:tagLimit 限度的是雷同的父节点层级,不论属性,是看布局的层级 8. 如何避免遍历的时候不小心跳到别的利用?跳到别的利用后怎么回来?答:会主动跳转回来的。除非设置了 App 的白名单 9. 页面须要在当前页不停滑动加载测试答:遍历完当前页后用 afterpage 参数设置滑动 10. firstList 和 lastList 能够写多个表达式吗?他们是如何执行的?答:程序是这样排列的 firstList[0]firstList[1] 排除 lastList firstList 之后剩下的元素 lastList[0]lastList[1]backbutton11. Appclawer ==>maxDepth: 这个层级是如何定义的?答:maxDepth 能够从 log 中看到,AppCrawler.log 中有一个 Stack 的输入,外面默认保留的是所有 activity 的栈记录。MainMain->UserProfileMain->UserProfile->LoginMainmaxDepth 是判断这个堆栈最长的长度,一旦超过就回退