UiAutomator 二次开发 uiautomatorviewer 优化定位符生成自动化代码实践总结分享

hello · April 23, 2018 · Last by hello replied at August 31, 2018 · 6080 hits

1,元素定位麻烦

UI自动化最烦的就是要机械重复的去定位元素,找Xpath,id等,虽然安卓SDK自带了uiautomatorviewer可以查找定位元素,但是里面的xpath太长,UI稍微修改一下,用例就无法通过了。我们需要的是一个相对短的xpth去定位元素,以此来保证UI变化时,对用例影响最小,基于此自带的uiautomatorviewer定位符需要优化。

2,复制粘贴的代码多

找到定位元素的方式后,写的最多的也许就是点点点了。翻译成代码就是【driver.findElement("//android.widget.ImageView[@content-desc='门票']","xpath").click();】,点击元素,输入,获取元素,占用了自动化绝大多数代码量,耗用很多时间,生成重复代码可以帮我们节约很多时间。

为了解决上述两问题,节省复写代码时间,汲取社区很多前辈的经验提供了很好的思路后,二次开发uiautomatorviewer优化定位符生成自动化代码。

上个效果图:

  • 定位符优化策略:主要修改源码UiNode,大家可以参考上面我列举的链接。
    修改com.android.uiautomator.tree.UiHierarchyXmlLoader,解析遍历xml,找到相对短的xpth去定位元素,uiautomatorviewer 二次开发之自动生成控件定位符说的很详细了。

  • 截图速度优化:主要改造UIAutomatorview,直接用ADB截图。
    主要用到我上一篇文章的方法uiautomatorviewer 获取不到动态页面解决办法调用UiDevice.dumpWindowHierarchy(),即解决了无法截取动态页面的问题,又提升了截图速度。修改com.android.uiautomator.UiAutomatorHelper

    private static void getUiHierarchyFile(IDevice device, File dst,
    IProgressMonitor monitor, boolean compressed) {
    if (monitor == null) {
    monitor = new NullProgressMonitor();
    }

    monitor.subTask("Deleting old UI XML snapshot ...");
    String strCmdMsg = "rm " + UIDUMP_DEVICE_PATH;

    try {
    CountDownLatch commandCompleteLatch = new CountDownLatch(1);
    device.executeShellCommand(strCmdMsg,new CollectingOutputReceiver(commandCompleteLatch));
    commandCompleteLatch.await(5, TimeUnit.SECONDS);

    strCmdMsg = "rm " + UISHOT_DEVICE_PATH;
    commandCompleteLatch = new CountDownLatch(1);
    device.executeShellCommand(strCmdMsg,new CollectingOutputReceiver(commandCompleteLatch));
    commandCompleteLatch.await(5, TimeUnit.SECONDS);
    } catch (Exception e1) {
    // ignore exceptions while deleting stale files
    }

    monitor.subTask("Taking UI XML snapshot...");
    try {
    CountDownLatch commandCompleteLatch = new CountDownLatch(1);
    strCmdMsg = String.format("%s %s %s", UIAUTOMATOR, "runtest LvmamaXmlKit.jar", "-c com.lvmama.uidump.DumpXml");
    device.executeShellCommand(strCmdMsg,new CollectingOutputReceiver(commandCompleteLatch));
    commandCompleteLatch.await(XML_CAPTURE_TIMEOUT_SEC, TimeUnit.SECONDS);

    monitor.subTask("Pull UI XML snapshot from device...");
    device.getSyncService().pullFile(UIDUMP_DEVICE_PATH,dst.getAbsolutePath(), SyncService.getNullProgressMonitor());
    } catch (Exception e) {

// throw new RuntimeException(e);
}
}

  • 添加右击菜单:监听选择项,同步点击或者输入手机内页面再截图,生成操作对应代码,类似录制不过是代码录制。
    找到开源包的com.android.uiautomator;UiAutomatorView这个java文件,主要修改这一块代码mScreenshotCanvas.addMouseListener(new MouseAdapter() {}

        mScreenshotCanvas.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseUp(MouseEvent e) {
    if (mModel != null) {
    mModel.toggleExploreMode();
    redrawScreenshot();
    }
    //右击
    if (e.button == 3)
    {
    Menu menu = new Menu(UiAutomatorView.this.mScreenshotCanvas);
    UiAutomatorView.this.mScreenshotCanvas.setMenu(menu);
    Menu clickTypeMenu = new Menu(menu);
    Menu editTypeMenu = new Menu(menu);
    Menu longPressMenu = new Menu(menu);
    Menu findTypeMenu = new Menu(menu);
    Menu menu4 = new Menu(menu);
    Menu sendkeyMenu = new Menu(menu);
    final MenuItem clickItm = new MenuItem(menu, 64);
    clickItm.setText("Click");
    clickItm.setMenu(clickTypeMenu);

    final MenuItem clkRfhItm = new MenuItem(menu, 64);
    clkRfhItm.setText("Click(ReShot)");
    }
    e.button == 3 就是获得右键事件的判断,给各个菜单绑定监听事件,完成相应的处理
    clickById.addSelectionListener(new SelectionAdapter()
    {
    public void widgetSelected(SelectionEvent e)
    {
    String src= getSourceByAction(clickById.getText(), clickItm.getText());
    outpuText(src);
    }
    });
    。。。。。

    同步输入

实践并总结一下各路大神的无私分享,谢谢各位授之于渔,如有雷同实属参照,改造工具没别的,跟着好的思路分享,就是干!非常感谢,期待大神们分享更多更好的工具思路。
jar包放到Git上了jar包和具体使用说明
刚完成雏形,还很多要完善的地方,欢迎大家不吝赐教!

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

源码可以放出来?

hello #2 · April 23, 2018 作者
恒温 回复

今天太晚了,明天看看吧

3Floor has been deleted

这个还可以兼容ios录制呢,好好玩 😀

hello #5 · April 24, 2018 作者
bauul 回复

真的么?我好像记得你发一篇苏宁的帖子,找不到你那篇链接了,没加上,参考了你的。你发个链接,我加上🎀 🎀

楼主这个jar包能共享出来不

hello #8 · April 24, 2018 作者
chengen 回复

可以。

Author only
hello #10 · April 24, 2018 作者
chengen 回复

放Git了,你去下一下吧。

hello #11 · April 24, 2018 作者
chengen 回复

可以用么?

Author only
hello #13 · April 24, 2018 作者
chengen 回复

LvmamaXmlKit.jar 是改进截取xml用的,要推到手机里。ADBKeyBoard.apk是同步输入,解决汉字输入问题的。可以不装,但是不装的话,就不能同步输入了。

hello 回复

请问l z的sdk是啥版本的呀?我这边在真机上试用获取不到源码哦

hello #15 · April 28, 2018 作者
water 回复

非常抱歉,我开发时,用的模拟器,真机没试过,我回头修改一下,以支持真机吧。你先用模拟器玩一下下吧😂

hello 回复

哈哈哈~~不错不错!加油撒!

hello #17 · April 28, 2018 作者
water 回复

你们都是土豪公司全部用真机,我们只能用模拟器,哎,不说了,我去借手机去了~

hello 回复

你好,文档这里文件名的修改与运行文件这里不是很清楚

  • 我电脑 sdk 文件夹只有 uiautomatorviewer.bat ,是用 \autotest_helper\下面的 uiautomatorviewer.jar 覆盖? 执行 uiautomatorviewer.jar 后连接不上,执行自己的 uiautomatorviewer.bat 可以连接上,不过就没有二次开发的功能。
iiFeng 回复

噢我看到了。文件路径这里没看清楚,uiautomatorviewer.jar 在文件夹 \tools\lib 里。运行成功了

不过,页面移动时会闪屏,底部驴妈妈的背景与我的页面混合显示,请问什么原因

hello #20 · June 08, 2018 作者
iiFeng 回复

闪屏问题,是设置背景图片的问题,我后期优化一下,非常抱歉啊

hello 回复

好~ 提了 issue

请问一下我部署好之后,打开uiautomatorviewer还是原来的旧页面呢,没有选择java和python的地方

hello #24 · August 06, 2018 作者
刘光磊 回复

那说明bat没有启动到新的jar包啊。你原来的包备份成.zip

这个跟用appium录制很像啊

hello #26 · August 31, 2018 作者
king 回复

录制我没试过,这个也是刚刚研究。Appium 还可以录制么,我研究学习一下

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up