起因

  今年年初的时候,公司让写个做自动化测试的工具,真头疼!我都没做过这,心里怕怕的,但交待我来做,我又不能不接,罢了,做!
  因为没做过,我只学过些 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 源码


↙↙↙阅读原文可查看相关链接,并与作者交流