前几年书写了一个技术SWING的界面测试的有些JAVA技术还比较有意思给大家分享一下。SWING界面自动测试关键技术:
1,  如何替换掉系统的消息队列
2,  如何识别事件
3,  如何记录
4,  如何回放第1个技术
使用 ActiveEventimport java.awt.AWTEvent;
import java.awt.ActiveEvent;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Event;
import java.awt.EventQueue;
import java.awt.MenuComponent;
import java.awt.event.MouseEvent;import javax.swing.JButton;
import javax.swing.JDialog;import nc.web.AWTAutoShutdown;public class EventDispatch extends AWTEvent implements ActiveEvent {  public static EventQueue theQueue;
  static{
  if (theQueue == null) {
    java.awt.Toolkit t = java.awt.Toolkit.getDefaultToolkit();
    theQueue = t.getSystemEventQueue();
  }
  }
  public static void replaceSysteEventDispatch() {
    try {
      //System.out.println("new frame");
      if (theQueue == null) {
        java.awt.Toolkit t = java.awt.Toolkit.getDefaultToolkit();
        theQueue = t.getSystemEventQueue();
      }
      theQueue.postEvent(new EventDispatch(null));
      
    } catch (Exception e) {
      e.printStackTrace();
      /** 可以是安全权限不能访问*/
    }
  }
  /** 虚礼一个对象 */
  private static JButton jb=new JButton();
  public EventDispatch(Event event) {
    super(new MouseEvent(jb,1,1,1,1,1,1,false),1);
  }  public void dispatch() {
    while (true) {
      try {
        AWTEvent event = theQueue.getNextEvent();
        /** 发送事件,可以在 Dialog.setModal(true) show ,接管事件 */
        EventDispatch ed=new EventDispatch(null);
        theQueue.postEvent(ed);
        
        if(event.getClass() == EventDispatch.class )
          continue;
        Object src=event.getSource();
        if (event instanceof ActiveEvent) {
     ((ActiveEvent)event).dispatch();
     } else if (src instanceof Component) {
     ((Component)src).dispatchEvent(event);
     } else if (src instanceof MenuComponent) {
     ((MenuComponent)src).dispatchEvent(event);
     } else {
     System.err.println("unable to dispatch event: " + event);
     }
        
      } catch (ThreadDeath death) {
        break;
      } catch (Throwable e) {
        System.err.println("Exception occurred during event dispatching:");
        e.printStackTrace();
      }
    }
  }} 

解决方案 »

  1.   

    鼠标事件是最难记录的,由于鼠标事件前后界面会改变,或者有的需要MousePressed事件 ,有的需要MouseRelease 所以
    在鼠标事件发送前后都需要进行处理
    在事件队列拿到的事件,是发送到Window上的底板的。
    所以需要根据代码取道它真正的控件对象
    public static Component getMouseEventTarget(Object org,MouseEvent me) 
    {
      Component targComponent=null;
      if(org instanceof Component)
      {
        targComponent = (Component) org;
        if(org instanceof Container)
        {
          Component temp=getMouseEventTarget((Container)org,me.getX(),me.getY());
          if(temp!=null)
            targComponent = temp;
        }
      }
      return targComponent;
    }
    鼠标事件究竟发送给谁的需要在不同的点进行识别:
    在鼠标 beforeMousePressed 需要识别:
      JTree,JTable,javax.swing.plaf.metal.MetalComboBoxButton
      需要识别单点双点beforeMouseRleased
    需要识别:JList
    afterMouseReleased
    需要识别:JList,JSlider,JToggleButton,JScrollBar
    其他事件简单的介绍一下:
    键盘事件处理:比较简单。
    记录发送给具有焦点的对象就可以了。
    itemEvent需要处理:javax.swing.JComboBox
    TextEvent :需要处理文字录入。
    WINDOW_CLOSING:处理节点关闭mouseMove:比较麻烦,大多数时候是无限的。 
      

  2.   

    正确识别事件记录比较简单:主要记录的是 COMPONENT的相对位置。比如:他在 XX控件上的YY位置上。最简单的办法是。将界面控件全部大列表,按照顺序,得到他在什么位置。什么控件类型上。建议大家记录后以JAVA 代码的形式记录,可以编辑重放。