UiAutomator 基于 uiautomator 与 shell 的自动化测试工具

bauul · 2015年10月12日 · 最后由 bauul 回复于 2018年07月02日 · 5406 次阅读
本帖已被设为精华帖!

起因

  今年年初的时候,公司让写个做自动化测试的工具,真头疼!我都没做过这,心里怕怕的,但交待我来做,我又不能不接,罢了,做!
  因为没做过,我只学过些 java,都毕业三四年了,哪记得那多,想着用 python 做,听说 python 容易上手,找了本 python 做 GUI 的书,全英文的,看了一遍,云里雾里的,没概念。思考再三,还是用 java 做,毕竟还有点基础不是,找了好几本用 java 做 GUI 的书,最后还是选中--《Java 开发利器:Eclipse SWT/Jface 核心应用》,这本书比较详细,靠谱。

怎么做

  这个工具点坐标就可以了吗?NO,要点控件,此前已经自学过 uiautomator,也写过许多 shell 做自动化测试的脚本(Shell+sendevent),所以我考虑将 uiautomator 与 shell 结合起来做,写出来的测试脚本是一个个的 shell 脚本,用 java 做电脑端编写自动化测试脚本的工具。点击控件,我所想到的实现方法有两种:

一种是:

  通过 uiautomator,通过传递参数到 uiautomator 脚本,将一些通用的方法,写出来,供 shell 来调用,比如我们可以在 eclipse 中,写一个 ClickByText 方法,然后在 shell 中调用,uiautomator runtest FileName.jar -c PackageName.ClassName -e text Phone,来点击 text 属性为 Phone 的控件。

    public UiObject objByText(String text) throws UiObjectNotFoundException{
    
      UiObject obj = new UiObject(new UiSelector().textMatches(text));
      return obj;       
    }
另一种是

  通过 uiautomator dump 生成 xml 文件,通过 shell 分析这个 xml 档,方法可见:[https://testerhome.com/topics/2806]

  所以,写出来的测试脚本,是 shell 脚本,我写了一个 Template.sh,这里面包含所有的通用操作,比如 Click,ClickByText,PinchIn 等等,其他的测试用例,都去调用这里面的方法。当然,不仅仅包含这些按键的方法,还包含测试设备状态的一些方法,比如抓取某一进程 memory(使用 procrank 命令)使用的大小保存到一 xls 表格中,等
  

  可以点击控件,但是不能在本工具查看控件,控件查看需要通过 uiautomatorviewer 这个工具,被同仁反鐀,不方便,虽然自我感觉还行啊!我在 eclipse 中用 uiautomator 写测试用例的时候,也是要看 uiautomatorviewer 的控件啊,习惯了,所以不觉得有什么问题。没有用过的同仁就觉得,呀,你为什么不能把 uiautomatorviewer 上面显示的控件信息,显示到你的工具上去呢,那样多好。

优点

  对比 uiautomator,我这还有一优点呢,选中一行,单击 debug 即可单步调试,而在 eclipse 中用 uiautomator 写测试用例时,则需要编译,push,最后才可执行

缺点

  因为测试用例都是 Shell 脚本,所以可以在后台跑,但是不能进 sleep 模式,进 sleep 模式,shell 会被挂起,直到唤醒后继续 run

后来

  后来,我在 testerhome 看到了 @cpfeng0124的帖子 [https://testerhome.com/topics/2632] ,这与我的想法刚好相反,我想在我的工具上加入 uiautomatorviewer 显示控件的信息,而这个贴子则是在 uiautomatorviewer 的基础上,加入了各种操作。但我没有找到 uiautomatorviewer 的源码,在群里一位叫文武不辉的同学的帮助下,找到了 uiautomatorviewer 的源码,然后我又基于 uiautomatorviewer 的源码,做了一新工具:

在开发过程中,就一同事用,各种 bug,被她各种吐槽,各种不爽,唉,不过还好,虽然做的慢,但还是做出来了。

碰到的一些问题(问题非常多,挑一两个主要的讲吧)

如何在点击控件时,自动获取控件的 instance 信息?

  开始我默认是点击 instance 为 1 的控件,后台在开会时,同事问我,是否可以自动抓到第几个控件,比如在上图中,我们看到当前选中的是第三个 text 属性为 Phone 的控件,工具就会在选择 Attribution operation > Click > text 之后,自动点击 text 属性为 Phone 的第三个控件,并刷新点击操作后的屏幕与控件信息到工具上来,我在 uiautomatorviewer 的源码 uiautomatorviewer.java 中加入了一列,用来显示 text,resource-id 及 content-desc 是第几个,这里是判断 text 属性是第几个控件的代码,

                     if (((AttributePair) element).key.equals("text")) {

                         List<BasicTreeNode> totalTreeNode = mModel.getmNodelist();

                         for (int i=0; i<totalTreeNode.size(); i++) {

                             BasicTreeNode selectedNode = mModel.getSelectedNode();

                             if (selectedNode.equals(totalTreeNode.get(i))) {
                                 //查找时,如果找到了当前选中的控件,则停止查找
                                 break;
                             } else {

                                 Object [] selectedElement = totalTreeNode.get(i).getAttributesArray();

                                 for (int j=0; j<selectedElement.length; j++) {

                                     if (((AttributePair) selectedElement[j]).key.equals("text")) {

                 //如果某一控件的text属性与当前选中的控件的text属性相同,则instance变量+1
                                         if (((AttributePair) selectedElement[j]).value.equals(((AttributePair) element).value)) {
                                             instance++;
                                         }
                                     }
                                 }
                             }
                         }

                         return String.valueOf(instance);
                     }
在使用 uiautomator dump 过程中发现,有时会发生 uiaumator 进程死锁,导致我的测试脚本卡死,不再继续执行,这里我通过 shell 判断,如果 2 秒钟后,进程仍在,将它杀掉:
KillUiautomator()
{
uiautomatorPID=`busybox ps|busybox grep uiautomator|busybox grep -v grep|busybox awk '{print $1}'`
if test ! "$uiautomatorPID" == ""
then
kill -9 $uiautomatorPID
fi
}

#这里调用的其实是uiautomator 中的UiDevice.getInstance().dumpWindowHierarchy(fileName);方法
uiautomator runtest /data/local/tmp/CommonAction.jar -c com.fih.liguo.GetAttributionXML&
busybox usleep 2000000
KillUiautomator

感谢

  首先,得感谢,让你最先痛苦的人,是公司的上司吧,如果不是他,我也不打算做这工具,其实公司另一部门有一自动化工具,这个就不细说了。然后要感谢 TesterHome 让我从不同的大牛的帖子中学到了许多知识与想法,感谢我那一直吐槽我的同事,催我改进工具啊!

未来

  这个工具,还可以继续优化,编辑区域可以优化,做成 shell 脚本代码高亮,伸缩显示等效果,可以将 ddms 的部分功能移植过来,等等

接下来的学习计划

  在学习 uiautomator2.0,同时想学一下 espresso,以及 html+css+javascript,用来做漂亮点的自动化测试报告。

uiautomatorviewer 源码

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 42 条回复 时间 点赞

不错,很棒的 gui 工具!

PS: testerhome 拼错了,少了 er

#1 楼 @chenhengjie123 尴尬,已更新,既然还可以,请点击 “喜欢”😍

没看明白,这个工具具体是如何进行自动化测试的?又怎么跟 shell 结合起来的?是否能详细分享一下?

4楼 已删除

挺好的,如果能把人工操作转化成脚本,然后以后可以批量执行,相信用的人会更多~

#3 楼 @happystone 更新了下,有问题可以回我,喜欢,请点击 “喜欢”,嘿嘿

#5 楼 @yangchengtest 你所说的,人工操作转成脚本,是说将逻辑测试转成脚本吗?还是怎么样?批量执行没有问题呀,这是 shell 测试脚本,批量不成问题的。

#6 楼 @carl 。。。分享技术,内敛宣传。

@carl 最好是将可视化的操作转化可以重复操作的内容。比如按键用 UI 操作,可以自动转成脚本,后续可以重复执行。仅供参考。

bauul #10 · 2015年10月13日 Author

#9 楼 @yangchengtest 现在按键(我这里指 Hardkey,比如 Power/Menu/Volume Down/Volume Up)用的是 keyevent,看过 uiautomator 的源码,也是用的这个啊!然后你说的的意思,我还是不太明白,可以讲的再清楚些么?感谢

对比自己和 @carl 的动手能力,惭愧啊。
虽然自己手上有很多资源,但是没做出什么像样的东西。
感谢 @carl 的分享啊。
(P.S:我是文武不辉)

很厉害!~

_^ 赞一个

@carl 我的意思是比如你一个按键就可以自动生成一条或数条脚本语言,然后这个脚本语言可以重复执行,这样不就啥也不会的人也可以跑脚本了么。
比如 CLICK 某个元素,就是 CLICK ITEM 类似这种翻译过的。

bauul #18 · 2015年10月13日 Author

#13 楼 @shixue33 哈哈,谢谢,听说咱们公司接下来还有一个 3D 的项目呢,估计还会再合作,嘿嘿

bauul #16 · 2015年10月13日 Author

#14 楼 @yangchengtest 这是可以的,现在工具本身就可以给不会的人用了,上手还是容易的,再次翻译,我在考虑有没有必要,封装太多,会导致效率低下的

工具放上来,让大家使用一下啊

bauul #22 · 2015年10月14日 Author

#17 楼 @562243985 还不够好

工具能分享出来么

bauul #21 · 2015年10月21日 Author

#20 楼 @itboyst
还不够好,做得自己能稍微满意就分享出来

屌屌的

楼主,看你说在研究 uiautomator 2.0,打算做漂亮一些的自动化报告,有什么进展么?我也想了解一下这方面的东西,./gradew cC 可以生成网页报告,界面还算漂亮。但如果需要执行部分用例就不好弄了,你有什么看法?

bauul #27 · 2016年01月28日 Author

#23 楼 @apple1987 初步完成了已经,需要学习 html, css, javascript 的知识

可否分享一下,O(∩_∩) O,也想学习一下

你这里的调试 和运行时 每次 push 那个 jar 包到 手机里么

bauul #30 · 2016年03月30日 Author

#26 楼 @taki
不需要啊,做一个通用版的操作就行,用例是 shell 脚本,直接调用。所以只需要 push 一次就 OK

#27 楼 @carl 每次执行 uiautomator 脚本是吧

bauul #32 · 2016年03月30日 Author

#28 楼 @taki 是 shell 脚本

#29 楼 @carl 安卓的 shell??

bauul #31 · 2016年03月30日 Author

#30 楼 @taki
安卓的 shell?这个问题很怪,不过或许可以这么说,可以借助 busybox

#31 楼 @carl 一直没做过移动端的东西,所以说到 shell,第一时间想到的就是 linux 服务器的 shell

bauul #36 · 2016年03月30日 Author

#32 楼 @taki
嗯,Android 与 linux 是有渊源的,Android 的内核是从 linux 移植过来的。那你之前 做什么?

#33 楼 @carl 我知道安卓是基于 linux ,之前都做 PC 端 的, 接口的 , 开发工具 ,开发系统什么的,最近想学学 appium 才有点接触

bauul #35 · 2016年03月30日 Author

#34 楼 @taki
哈哈,互相学习

@carl 能够把该工具分享,互相学习一下呗

bauul #40 · 2016年05月13日 Author

#36 楼 @yangmingquan6
等到 6 月底争取开源

38楼 已删除

前辈,我是小米工程师,想加个微信好友交流下,我的微信是 shaoxy1992.

bauul #42 · 2017年05月02日 Author
翔宇 回复

你好,加了

恒温 感谢 fir.im —— 结果公布 中提及了此贴 06月05日 13:20
匿名 · #42 · 2018年06月30日
仅楼主可见
bauul #43 · 2018年07月02日 Author

嗯,4 年

匿名 · #4 · 2018年07月02日
仅楼主可见
bauul #45 · 2018年07月02日 Author

😊

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册