UI 自动化最烦的就是要机械重复的去定位元素,找 Xpath,id 等,虽然安卓 SDK 自带了 uiautomatorviewer 可以查找定位元素,但是里面的 xpath 太长,UI 稍微修改一下,用例就无法通过了。我们需要的是一个相对短的 xpth 去定位元素,以此来保证 UI 变化时,对用例影响最小,基于此自带的 uiautomatorviewer 定位符需要优化。
找到定位元素的方式后,写的最多的也许就是点点点了。翻译成代码就是【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 包和具体使用说明
刚完成雏形,还很多要完善的地方,欢迎大家不吝赐教!