Wednesday, April 20, 2011

Testing SWT application with SWTBot

SWTBot is open-source Java based UI/functional testing tool for testing SWT and Eclipse based applications.

SWTBot provides APIs that are simple to read and write. The APIs also hide the complexities involved with SWT and Eclipse. This makes it suitable for UI/functional testing by everyone, not just developers. SWTBot also provides its own set of assertions that are useful for SWT. You can also use your own assertion framework with SWTBot.

There are many articles present for SWTBot for Eclipse Plug-in and RCP applications. Refer the following links for more details:
As the title suggest, the intention of this article to demonstrate the testing of a stand-alone SWT UI. There was a question asked  on the Stackoverflow with the same problem. You can checkout my answer there also. For completeness purpose I am posting it here too.

Well it is very much possible to test simple SWT application with SWTBot. Follow the step as mentioned below.
  1. Download SWTBot for SWT Testing
  2. Put it in the <eclipsehome>/dropins folder (although not required for non-plug-in projects)
  3. Restart your eclipse (not required if you adding the SWTBot jars in a simple Java project)
Now at this point you are ready to play with SWTBot.

For the demo purpose I have written a small Login dialog for you and it will look like this:


>>Code
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class SampleSWTUI 
{
   public Shell showGUI(final Display display)
   {
       Shell shell = new Shell(display);
       shell.setLayout(new GridLayout(3,true));
       shell.setText("Sample SWT UI");

       new Label(shell, SWT.NONE).setText("User Name: ");
       final Text nameText = new Text(shell, SWT.BORDER);
       nameText.setText ("");
       GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
       data.horizontalSpan = 2;
       nameText.setLayoutData(data);

       new Label(shell, SWT.NONE).setText("Password: ");
       final Text passwordText = new Text(shell, SWT.BORDER|SWT.PASSWORD);
       passwordText.setText ("");
       data = new GridData(SWT.FILL, SWT.FILL, true, false);
       data.horizontalSpan = 2;
       passwordText.setLayoutData(data);

       Button loginButton = new Button (shell, SWT.PUSH);
       loginButton.setText ("Login");
       data = new GridData(SWT.FILL, SWT.FILL, true, false);
       data.horizontalSpan = 3;
       loginButton.setLayoutData(data);
       loginButton.addSelectionListener(new SelectionAdapter(){
           public void widgetSelected(SelectionEvent e) {
                String user = nameText.getText();
                String password = passwordText.getText();

                System.out.println("\n\n\n");
                if(user.equals("Favonius") && password.equals("abcd123")){
                    System.out.println("Success !!!");
                }else {
                    System.err.println("What the .. !! Anyway it is just a demo !!");
                }                   
           }
       });

       shell.pack();
       shell.open();
       return shell;
   }

   public static void main(String [] args) 
   {
       Display display = new Display();
       Shell shell = new SampleSWTUI().showGUI(display);
       while (!shell.isDisposed()) {
           if (!display.readAndDispatch()) display.sleep();
       }

       display.dispose();
   }
}
Now create a JUnit test case (google for it if you are new to it) . Also add all the jar files present in SWTBot (the one you have downloaded) in your classpath.

Now first create a display (because application needs one). Also get the handle of container in which your widgets/controls are present. In my case it is the Shell. Although the below code is self descriptive, still, I will suggest you to refer its Javadoc.

>>SWTBot Code
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swtbot.swt.finder.SWTBot;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
import org.junit.Test;

import junit.framework.Assert;

public class SWTBotDemo 
{
    @Test
    public void test() 
    {
        SWTBotPreferences.PLAYBACK_DELAY = 100; // slow down tests...Otherwise we won't see anything
  
        Display display = new Display();
        Shell shell = new SampleSWTUI().showGUI(display);
        SWTBot bot = new SWTBot(shell);
  
        SWTBotButton loginButton = bot.button("Login");
        SWTBotText userText = bot.textWithLabel("User Name: ");
        SWTBotText passwordText = bot.textWithLabel("Password: ");
  
        userText.setFocus();
        userText.setText("Superman");
  
        Assert.assertEquals(userText.getText(),"Superman");
  
        passwordText.setFocus();
        passwordText.setText("test123");
  
        Assert.assertEquals(passwordText.getText(),"test123");
  
        loginButton.setFocus();
        loginButton.click(); 
  
  
        userText.setFocus();
        userText.setText("Favonius");
  
        Assert.assertEquals(userText.getText(), "Favonius");
  
        passwordText.setFocus();
        passwordText.setText("abcd123");
  
        Assert.assertEquals(passwordText.getText(), "abcd123");
  
        loginButton.setFocus();
        loginButton.click();
        
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }

        display.dispose();
    }
}
Now all the SWTBot methods and variables are well defined in the source and the source is bundled within the SWTBot jars. So you can always go ahead and hack its source code.

>>Further Reading
  1. SWTBot FAQ

No comments:

Post a Comment