Java Swing应用使用Arthas自动化
一直以来,Java的Swing桌面应用自动化测试非常不便,需要对元素进行定位再进行操作,目前业界没有比较好的自动化工具,但经过探索,发现通过阿里的Arthas工具来对Java的Swing应用进行自动化非常简单方便。
Arthas是什么
Arthas是阿里开源的一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
Arthas的vmtool
Arthas有一个命令vmtool可以从从 jvm 里查询对象并执行一些OGNL表达式,因此我们可以通过vmtool查询到swing的组件实例,并根据一些条件(比如title、text、是否显示等)进行过滤,获取我们想要的组件实例,并直接调用该组件实例的方法(比如点击、关闭、设置值等),达到自动化效果,也可以获取该实例的大小和位置,然后对其进行操作。
使用示例
启动Arthas
- 在启动Java程序后,启动Arthas,选择需要自动化的进程
- 启动之后,可以使用命令行或者REST进行操作,本文后面的示例都使用REST接口
查询按钮并点击
目标:点击界面上的【确认(C)】按钮
- 这个组件是JButton,文本是: 确认(C),正在界面上显示, 因此我们需要查询所有JButton的实例,并过滤出正在显示且文本等于确认(C)的JButton实例
- 具体的命令是
vmtool --action getInstances --className javax.swing.JButton --limit 1000 --express 'instances.{? #this.getText() == \"确认(C)\" && #this.isShowing()}--limit的默认值10,实例只会默认显示10条,有时候可能很多,因此需要给大点--express是我们要执行的表达式,{? #this.getText() == \"确认(C)\" && #this.isShowing()}过滤出正在显示且文本等于确认(C)的示例
- 过滤完成后可以使用.size()查询结果的数量
vmtool --action getInstances --className javax.swing.JButton --limit 1000 --express 'instances.{? #this.getText() == \"确认(C)\" && #this.isShowing()}.size()',可以看到结果只有一个 - 查询到结果后,调用doClick()点击,可以发现界面上的按钮已被点击消失了
- JButton组件有doClick方法,但其他组件可能没有,直接调用实例的方法需要确认根据实例类型的不同调用不同的方法,比如JLable的点击,需要先获取JLable的鼠标事件,再调用点击方法
查询组件的位置和大小
直接获取组件并调用组件的方法可以完成绝大多数场景,但界面有时候有阻塞之类的,那么Arthas也会一直阻塞,因此直接获取组件的大小和位置,然后计算组件的中心,并点击该中心位置也可以达成我们目的,这里就展示下如何获取组件的位置和大小
- 获取JLable组件【打开】的位置
vmtool --action getInstances --className javax.swing.JLabel --limit 1000 --express 'instances.{? #this.isShowing() && #this.getText() == \"打开\"}'[0].getSize() - 获取组件的大小
vmtool --action getInstances --className javax.swing.JLabel --limit 1000 --express 'instances[0].getSize()'