Using UISpec4J

UISpec4J is probably the coolest and most useful thing I used at Nortel for Unit testing GUIs. It allows you to write tests that intercept the window and inject all kinds of things like mouse clicks, entering text and the like. Still, there is no automated way to test for if a window just looks funny. That is something you just have to eyeball.

Here is a quick example. Take the following code.

package com.stave.gui.exercises;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

// Creates two buttons and a label to indicate what
// was pressed.
public class ButtonDemo extends JPanel implements ActionListener {

  JLabel jlab;

  ButtonDemo(){

    //Create the frame and get the Content Pane
    JFrame jfrm = new JFrame("A Button Example");
    Container container = jfrm.getContentPane();

    //Add the layout to the container
    container.setLayout(new FlowLayout());

    jfrm.setSize(220, 90);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Create some buttons, add the listener and
    //then add to the container
    JButton jbFirst = new JButton("First");
    JButton jbSecond = new JButton("Second");

    jbFirst.addActionListener( this);
    jbSecond.addActionListener(this);

    container.add(jbFirst);
    container.add(jbSecond);

    jlab = new JLabel("Press a Button");
    jlab.setName("Output");

    container.add(jlab);

    //Set the frame as visible
    jfrm.setVisible(true);

  }

  public static void main(String [] args){

    //Always better idea to have the frame
    // running in a separate Thread
    SwingUtilities.invokeLater(new Runnable() {
      public void run(){
        new ButtonDemo();
      }
    });
  }

  //private class buttonListener extends ActionListener{
  public void actionPerformed(ActionEvent e) {

    if(e.getActionCommand().equals("First")){
      jlab.setText("First Button Pressed");
    } else {
      jlab.setText("Second Button Pressed");
    }

  }

}

You end up with JPanel like this.

snapshot

The UISpec4J code is as follows.

package com.stave.gui.exercises;

import org.uispec4j.Button;
import org.uispec4j.TextBox;
import org.uispec4j.Trigger;
import org.uispec4j.UISpec4J;
import org.uispec4j.UISpecTestCase;
import org.uispec4j.Window;
import org.uispec4j.interception.WindowInterceptor;

public class ButtonDemoTest  extends UISpecTestCase {

  //Need to call this to initialize UiSpec4J
  static	{
    UISpec4J.init();
  }

  Window window;

  //Intercept the window and store it off
  protected void setUp() throws Exception {
    window = WindowInterceptor.run(new Trigger() {
      public void run() {
        new ButtonDemo( );
      }
    });
  }

  public void testButtons(){

    Button firstButton = window.getButton("First");
    Button secondButton = window.getButton("Second");

    assertNotNull(firstButton);
    assertNotNull(secondButton);

    //Its better to get these by name
    TextBox theLabel = window.getTextBox("Output");

    System.out.println(theLabel.toString());
    assertEquals(theLabel.getText(),"Press a Button");

    firstButton.click();
    assertEquals(theLabel.getText(),"First Button Pressed");

    secondButton.click();
    assertEquals(theLabel.getText(),"Second Button Pressed");

  }
}