JFCUnit

发表于:2007-05-25来源:作者:点击数: 标签:使得jfcunit实战介绍
JFCUnit实战 JFCUnit介绍 JFCUnit使得你能够为 Java 偏移应用程序编写测试例子。它为从用代码打开的窗口上获得句柄提供了支持;为在一个部件层次定位部件提供支持;为在部件中发起事件(例如按一个按钮)以及以线程 安全 方式处理部件测试提供支持。JFCunit
JFCUnit实战

JFCUnit介绍
JFCUnit使得你能够为Java偏移应用程序编写测试例子。它为从用代码打开的窗口上获得句柄提供了支持;为在一个部件层次定位部件提供支持;为在部件中发起事件(例如按一个按钮)以及以线程安全方式处理部件测试提供支持。JFCunit的基本测试思路是:它提供了很多方法,可以用来模拟许多本应由传统测试人员手工进行的触发事件,如:点击按钮,给文本框输入字符或数字,鼠标双击事件等,从而实现了测试的自动化。这一优点在需用户输入大量信息的界面测试中显的尤为重要。实际上JFCUnit的测试用例十分像RobotJ中的脚本的编写,使用熟练后对于自动化大批量测试十分有意义。
    更加详细的介绍可以参考本人前面贴过的相关主题“ZT:JUNIT用于界面测试中的增强版JFCunit,建议用其进行界面单元测试”,这里不再敷诉。
使用示例
    以下是一个具体实例,测试对象是一个Jdialog,界面效果如下:
 
我们设计的测试目的是:
1、    检查界面上是否存在各个设计组件;
2、    在用户名和密码为空的情况下,模拟点击确定按钮事件,是否能在原来的对话框上显示一个错误提示框,提示框的标题为"Login Error";
即最后显示效果如下:
 
以下是相关的测试对象代码和测试用例代码。
测试对象代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.borland.jbcl.layout.*;
import java.awt.BorderLayout;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author leiwei
 * @version 1.0
 */

public class LoginScreen extends JDialog{
  JPanel jPanel1 = new JPanel();
  JLabel jLabel1 = new JLabel();
  JLabel jLabel2 = new JLabel();
  JTextField LoginNameTextField = new JTextField();
  JButton EnterButton = new JButton();
  JButton ExitButton = new JButton();
  BorderLayout borderLayout1 = new BorderLayout();
  JPasswordField PasswordTextField = new JPasswordField();
  String title ="";
  private GridBagLayout gridBagLayout1 = new GridBagLayout();
  public LoginScreen(String ititle) {
    try {
      jbInit();
      super.setTitle(ititle);
    }
    catch(Exception e) {
      e.printStackTrace();
    }

  }
  private void jbInit() throws Exception {
    this.setName("loginScreen");
    this.setTitle(title);
    this.setBounds(300,300,300,300);
    jLabel2.setFont(new java.awt.Font("Dialog", 0, 13));
    jLabel2.setText("密 码:");
    jLabel1.setFont(new java.awt.Font("Dialog", 0, 13));
    jLabel1.setText("用户名:");
    jPanel1.setLayout(gridBagLayout1);
    this.getContentPane().setLayout(borderLayout1);
    EnterButton.setFont(new java.awt.Font("Dialog", 0, 12));
    EnterButton.setText("确定");
    EnterButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        EnterButton_actionPerformed(e);
      }
    });
    ExitButton.setFont(new java.awt.Font("Dialog", 0, 12));
    ExitButton.setText("取消");
    ExitButton.addActionListener(new java.awt.event.ActionListener(){
      public void actionPerformed(ActionEvent e) {
        ExitButton_actionPerformed(e);
      }
    });
    LoginNameTextField.setText("");
    PasswordTextField.setText("");
    jPanel1.add(jLabel1,  new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(52, 49, 0, 0), 0, 0));
    jPanel1.add(LoginNameTextField,    new GridBagConstraints(1, 0, 2, 1, 1.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(52, 7, 0, 73), 214, 0));
    jPanel1.add(PasswordTextField,       new GridBagConstraints(1, 1, 2, 1, 1.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(17, 7, 0, 73), 214, 0));
    jPanel1.add(jLabel2,   new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(19, 49, 0, 7), 0, 0));
    jPanel1.add(EnterButton,   new GridBagConstraints(0, 2, 2, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(35, 88, 62, 0), 12, 0));
    jPanel1.add(ExitButton,   new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(38, 91, 62, 73), 13, 0));
    this.getContentPane().add(jPanel1, BorderLayout.CENTER,0);
    this.pack();
    ExitButton.setName("ExitButton");
    EnterButton.setName("EnterButton");
    LoginNameTextField.setName("LoginNameTextField");
    PasswordTextField.setName("PasswordTextField");
  }


  public void show(){
    super.show();
  }
  public static void main(String args[]){
    JDialog dialog = new LoginScreen("loginScreen");
    dialog.show();
  }

  void ExitButton_actionPerformed(ActionEvent e) {
    System.exit(0);
  }

  void EnterButton_actionPerformed(ActionEvent e) {
    if(this.PasswordTextField.getPassword().length == 0){
      javax.swing.JOptionPane.showMessageDialog(this,"Login Error","Login Error",JOptionPane.ERROR_MESSAGE);
    }
  }
}

测试用例代码:

import java.util.*;

import javax.swing.*;

import junit.extensions.jfcunit.*;
import junit.extensions.jfcunit.eventdata.*;
import junit.framework.*;
import org.apache.regexp.*;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author leiwei
 * @version 1.0
 */

public class LoginScreenTest
    extends JFCTestCase {

  private LoginScreen loginScreen = null;
  private TestHelper helper = null;

  public LoginScreenTest(String name) {
    super(name);
  }

  protected void setUp() throws Exception {
    super.setUp();
    helper = new JFCTestHelper();
    loginScreen = new LoginScreen("LoginScreenTest: " + getName());
    loginScreen.setVisible(true);
  }

  protected void tearDown() throws Exception {
    loginScreen = null;
    helper.cleanUp(this);
    super.tearDown();
  }


  public void testUI() {
    JDialog dialog;

    JButton exitButton = (JButton) helper.findNamedComponent("ExitButton",
        loginScreen, 0);
    assertNotNull("Could not find the Exit button", exitButton);

    JButton enterButton = (JButton) helper.findNamedComponent("EnterButton",
        loginScreen, 0);
    assertNotNull("Could not find the Enter button", enterButton);

    JTextField userNameField = (JTextField) helper.findNamedComponent(
        "LoginNameTextField", loginScreen, 0);
    assertNotNull("Could not find the userNameField", userNameField);

    assertEquals("Username field is empty", "", userNameField.getText());

    JTextField passwordField = (JTextField) helper.findNamedComponent(
        "PasswordTextField", loginScreen, 0);
    assertNotNull("Could not find the passwordField", passwordField);

    assertEquals("Password field is empty", "", passwordField.getText());

    try {
      helper.enterClickAndLeave(new MouseEventData(this, enterButton));
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }

    List showingDialogs = helper.getShowingDialogs(loginScreen);
    assertEquals("Number of dialogs showing is wrong", 2, showingDialogs.size());

    dialog = (JDialog) showingDialogs.get(1);
    assertEquals("Wrong dialog showing up", "Login Error", dialog.getTitle());

    helper.disposeWindow(dialog, this);
  }





  public static Test suite() {
    return new TestSuite(LoginScreenTest.class);
  }


  public void TestUI(){}

  public static void main(String args[]) {
    junit.textui.TestRunner.run(suite());

  }

}

小结
1、    JFCUnit的基本框架与原理与Junit一样,其实从实现上是完全基于Junit,是Junit在GUI界面测试上的有效扩展。
2、    JFCUnit功能十分强大,擅长对象实例检查,各种人机界面响应事件的模拟,便于功能性检查。
3、    JFCUnit不善于界面布局,美观方面的检查,看来人工测试还是不可缺少的。
4、    JFCUnit中对对象进行测试的基础是获得测试对象实例,关键是find…Component系列API的应用,具体查找主要基于两个方面,对象组件的“Name”属性和在容器中的Index,而这两种方式都不是很直观,具体使用何种方式也很大程度上取决于开发人员的编码,具体使用时有一定难度和局限性。
5、    JFCUnit还有很多深入用法,比如支持GUI测试的多线程方法,支持XML方式测试,以后有时间再与大家分享。
6、    由于相关资料比较缺乏,很多测试经验完全是个人摸索得来,希望以后有人做更深入的研究。


相关资料
【1】    http://sourceforge.net/
【2】    http://epoxy.mrs.umn.edu/
【3】    《JFCunit 在单元测试中的应用》

原文转自:http://www.ltesting.net