Android自动化测试之Monkeyrunner解决ID重复问题

2024-03-26 04:18

本文主要是介绍Android自动化测试之Monkeyrunner解决ID重复问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文:

http://www.51testing.com/html/81/22381-854342.html

 

时光过得太快了,一晃离上一篇monkeyrunner系列的博客已经一年多了。这一年多时间经历了太多改变,一直没时间好好去总结和分享。直到今天在微博上和朋友聊到monkeyrunner,才想起趁这个机会再总结一下之前所积累的一些经验和技巧,在这里再次和大家分享下,也算是将这个从零开始系列再进一步,呵呵。  

现在说起Android端的功能自动化测试工具,其实还是蛮多的了,像很早就风靡的Robotium,后起之秀Uiautomator,跨平台的appium等,几乎从工具这个层面还是可以满足大家的要求了。MonkeyRunner作为其中的一员,其实并不能算是特别好用的一款,我平时用得就不多。因为毕竟从SL4A衍生出来,不是基于Android的直系血亲Instrumentation,天生就有运行速度慢,容易出错,可用的接口少等缺点,可谓是有点“先天不足”。当然优点还是有的,比如基于Jython语言来编写,语法简单易学,可以跨应用,可以直接以ID来操作测试,不需要签名等其他工具不具有的一些特点,所以有时也有它的用武之地,大家学习和掌握它之后应该也有一些机会是可以用到它的,紧急时候救救急啥的也还不错。  

既然Monkeyrunner先天不足,如果想要让它好用的话,那当然就只能后天补足了。前段时间在网上找到一个非常强大的monkeyrunner的第三方库wrapEasyMonkey,是基于EasyMonkeyDevice来二次封装的,并加入了自动异常处理、失败重试、case管理、断言、获取控件上的文本等,大大增强了monkeyrunner本来的功能,使得monkeyrunner强大了不止一个级别。除了运行还是比较慢这个没法解决之外,可以说其他的几乎都有了较大的改善。说句实话,原生monkeyrunner几乎没法直接使用。所以建议选用monkeyrunner作为自己的测试工具的童鞋,都可以去找找这个包来用用,确实挺好用的。具体的用法我这里就不啰嗦了,作者的教程还是写得蛮细的,相信有一定python基础的童鞋都应该看得懂。但在这里,我想重点分享的还不止这个第三方包,还有我个人对这个包的一些改进的想法。在wrapEasyMonkey的作者提供的包里,很多方法都是根据控件ID来操作的,比如getView(self,id)。但经常做Android自动化测试的朋友肯定都知道这里有个问题,很多时候我们的app里的控件要么没有ID,要么ID值就是重复的。在这种情况下,根据ID肯定是无法获取到这个控件的引用的。那么怎么办呢?我当时也是为这个问题非常地苦恼,但后来我仔细研究了Hierarchy Viewer得到的控件树形图,其实我们完全可以基于每个控件所在的子节点的位置,结合python函数的不定参数的特性,去获取任意已知ID的父节点的任意子节点的引用,然后再用这个引用作为参数去获取其对应的文本、断言等等,就方便多了,再也不会受到没有ID或者是ID重复的限制了。当然,要达到这样的功能需要修改原来那个包里的部分函数。

这里我举个实际例子来说明一下吧。假如我们现在就来测试一下Android自带的contact联系人那个app,假设我们先加上了一个联系人,现在我们用monkeyrunner来验证一下我们加入的联系人的信息是否正确。这里实际上就涉及到几个比较重要的操作:1. 获取对应的控件 2. 判断上面的文字是否和预期一致,也就是下面图上三个红色框所表示的部分。hierarchy viewer里的完整的图比较大,这里显示不了,所以大家可以自己通过这个hierarchy viewer来看看。



通过hierarchy viewer里显示的树形结构来看,这里显示电话号码158xxxxxxxx的控件和邮箱地址41420872@qq.com的控件ID都为text2,很明显,重复了。所以没法用原包里的getView(self,id)方法来获取这个view的引用。那是不是就没办法了呢?其实我们可以换个角度来看,即不从ID角度,而是从这个控件树的节点角度来思考如何获得控件的引用。我们可以看到在hierarchy viewer图中的每个控件所对应的框形中,右下角都有一个数字,如下图中红色框中的0和1所示。




其实这个数字就是该控件在同级兄弟节点中的索引值,我们知道这个索引值后,就可以根据parentView.children[index]属性来获取任意父节点所对应的子节点的对象引用。其中的parentView可以是树形图中有有效ID的任意父节点,然后利用python函数的可变参数列表特性来传入所需控件的索引列表即可构造出得到任意节点引用的字符串,从而得到其引用。核心代码如下:

def getChildView(self, parentId, *childSeq):
    hierarchyViewer = self.device.getHierarchyViewer()
    str_getchildview="hierarchyViewer.findViewById('" + parentId +"')"    
    for index in childSeq:       
        str_getchildview+=('.children[' + str(index) + ']')         
    exec 'child_view=' + str_getchildview
    return child_view

现在我们来看看这段代码如何使用。比如我们刚刚那个联系人的详细信息界面的联系人号码控件的hierarchy viewer截图如下:



联系人号码控件的对象引用可由这个语句获得:phone_number=device.getChildView('id/contact_data', 0, 0, 1, 0)。其中“contact_data”这个是其父对象的ID,这个ID必须符合两个条件,即有效和唯一。通过这个ID,我们就可以得到它的任意子孙节点的引用,0,0,1,0则是联系人控件在对象树中的索引链上的位置,大家对照着图应该很容易理解。有了这个引用之后,我们就比较好对所有以ID作为参数的方法来做改造了,你想改哪个就改哪个。这里我举个例子,比如原来wrapEasyMonkey包里有个方法是用来取得控件上的文本的getTextById(self,id),这也是我们要验证文字时所必须要用到的方法。但如上图所示,其实联系人的控件的ID是有重复的(跟邮箱地址那个控件的ID重复),我们不可能用这个重复的ID去调用getTextById方法,所以我们就只能根据刚刚我写的那个方法来先得到联系人控件的引用,再将获取文本这个方法改成根据传view的引用来获取文本。核心代码如下:

def getText(self,view):
    if view != None:        
         return (view.namedProperties.get('mText').toString().split('=')[1]).encode('utf8')

这下就要灵活很多了,就算你要获取那个对象没有ID或者ID是重复的,都不影响你的操作,因为它在对象树中的位置不可能重复,呵呵。  

好了,这次就说这么多了吧。这里我只是就我自己的一些想法和感受写一些抛砖引玉的文字,有不对的地方欢迎各位指正,当然也欢迎各位看官提出更多的想法,一起来改进我们的工具,将Android平台的自动化做得更好,呵呵。

这篇关于Android自动化测试之Monkeyrunner解决ID重复问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/847256

相关文章

Vue3绑定props默认值问题

《Vue3绑定props默认值问题》使用Vue3的defineProps配合TypeScript的interface定义props类型,并通过withDefaults设置默认值,使组件能安全访问传入的... 目录前言步骤步骤1:使用 defineProps 定义 Props步骤2:设置默认值总结前言使用T

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

504 Gateway Timeout网关超时的根源及完美解决方法

《504GatewayTimeout网关超时的根源及完美解决方法》在日常开发和运维过程中,504GatewayTimeout错误是常见的网络问题之一,尤其是在使用反向代理(如Nginx)或... 目录引言为什么会出现 504 错误?1. 探索 504 Gateway Timeout 错误的根源 1.1 后端

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

解决升级JDK报错:module java.base does not“opens java.lang.reflect“to unnamed module问题

《解决升级JDK报错:modulejava.basedoesnot“opensjava.lang.reflect“tounnamedmodule问题》SpringBoot启动错误源于Jav... 目录问题描述原因分析解决方案总结问题描述启动sprintboot时报以下错误原因分析编程异js常是由Ja

Python自动化处理PDF文档的操作完整指南

《Python自动化处理PDF文档的操作完整指南》在办公自动化中,PDF文档处理是一项常见需求,本文将介绍如何使用Python实现PDF文档的自动化处理,感兴趣的小伙伴可以跟随小编一起学习一下... 目录使用pymupdf读写PDF文件基本概念安装pymupdf提取文本内容提取图像添加水印使用pdfplum

基于Python实现自动化邮件发送系统的完整指南

《基于Python实现自动化邮件发送系统的完整指南》在现代软件开发和自动化流程中,邮件通知是一个常见且实用的功能,无论是用于发送报告、告警信息还是用户提醒,通过Python实现自动化的邮件发送功能都能... 目录一、前言:二、项目概述三、配置文件 `.env` 解析四、代码结构解析1. 导入模块2. 加载环

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模