Abbot for SWT: workbench wizard howto

summary

A brief, crude sketch (to be improved!) of how to write a simple testcase for an existing workbench wizard.

details


The pattern for testing workbench stuff is something like the
following, which uses a (working) wizard test of mine as example. It's
also pretty raw/ugly--this is early days--so please be charitable.
 Note that the following snippets are all

Licensed Materials -- Property of IBM
(c) Copyright International Business Machines Corporation, 2000, 2003
US Government Users Restricted Rights - Use, duplication or disclosure
restricted by GSA ADP Schedule Contract with IBM Corp.

and available under the terms of the Common Public License

http://www.opensource.org/licenses/cpl.php 

Basically, you need to provide some UI support (if only intellectual),
then code your fixtures and testcases. For the wizard example:

* UI: instrument where possible, learn where not.

- tag your widgets using Widget.setData(String, String).
  E.g. in my createProjectControl()

> public static Object[] createProjectControl(
> Composite parent,
> final String cLabel,
> final String tTip,
> final String bLabel,
> Listener bListener,
> final String bTip) {

>   Label l = createLabel(parent, cLabel);
>   // instrument for testing
*   l.setData("name", "projectControlLabel");
>   Composite c = createSkinnyComposite(parent, 2);
>   Text t = createText(c, DEFAULT_TEXT_STYLE | SWT.READ_ONLY);
*   t.setData("name", "projectControlText");
>   setAccessibility(t, cLabel);
>   t.setToolTipText(tTip);
>   Button b = createPushButton(c, bLabel);
*   b.setData("name", "projectControlButton");
>   b.addListener(SWT.Selection, bListener);
>   b.setToolTipText(bTip);
>   return new Object[] {l, t, b};
> }

  (We use the name attribute consistently. We probably need API to
  abstract this.) Below I will use the tags projectControl{Button,
  Label, Text} defined above to find those widgets.

- learn useful info about your widget's context. E.g. every workbench
  wizard has Back, Next, Finish, and Cancel buttons contributed by
  WizardDialog, which is Eclipse code that I don't wanna touch. To
  find, e.g., the Finish button, I note that it's a Button
  (Button.class), its text is "&Finish" (in English--I need to hit the
  properties file), and it's in my wizard, which has frame title= "New
  Action Mapping" (same i18n comments apply).

* setUp(): for wizard testing, the sequence is something like (note
  possibly unnecessary stuff within)

- find the workbench, its Window, the Window's Shell, and the Shell's
  Display

- if necessary, create one or more projects in the workbench (most
  wizards need some context into which to do something), and any
  needed artifacts therein. (Note that one of the main factors gating
  the success of automated GUI testing of Eclipse plugins will likely
  be the ready, user-friendly availability of a large stock of
  fixtures. Your assistance would be appreciated.)

- create a StructuredSelection with which to init the wizard (using
  created project(s))

- use the Display to syncExec(new Runnable() { public void run() { ...
  }}) the init(...), create(), and open() of the wizard

- get the Shell of the open wizard (explained below)

* testcase: do a syncExec(new Runnable() { public void run() { ... }})
  in which you

- read widgets. E.g., for the Text tagged above, it's straight Abbot:

> WidgetReference ref = new WidgetReference(
> "projectControlText", Text.class, "projectControlText");

  Since I can give the Finder a tag, I don't need much else.

> Text projectControlText =
> (Text)DefaultWidgetFinder.getFinder().findWidget(ref);

  After I have the widget, it's just straight JUnit (and SWT):

> assertTrue("projectControlText not enabled",
> projectControlText.getEnabled());
> assertFalse("projectControlText is writable",
> projectControlText.getEditable());

- do things to widgets. E.g., for the untagged Finish button:

> ref = new WidgetReference("finishButton", Button.class, null, null,
> ACTIONMAPPING_GENERIC_REGIONPAGE_TITLE, FINISH_BUTTON_TEXT);

  Since I have no tag, I give more information (frame title and button
  text). (I could give less information, but that would risk Abbot
  throwing an exception if it couldn't find the widget.) I also bound
  the search ...

> Button finishButton =
> (Button)DefaultWidgetFinder.getFinder().findWidget(ref, ourShell);

  to the wizard's shell (ourShell), discovered in setUp(). I can then
  inspect the button

> assertTrue("finishButton is disabled", finishButton.getEnabled());

  and click on it.

> tester.actionClick(finishButton);

  Note that I did NOT pass any information about the location of the
  Button! Abbot takes care of all that mess. This is IIRC a win over
  RobotJ/XDE Tester: no problems with display size, resolution, or
  where stuff ends up on the screen. The only thing you need to do @
  runtime is make sure that the UI is uncovered: Robot is, like a
  "real user," unable to click on a widget it can't see. (abbotforswt
  should also work in any version of Eclipse, although we have only
  tested in 3.0-M3, the latest stable build.)

* Include your testcase in one or more suites, and run them via
  pde.junit (if you have installed that plugin) or WebSphere Studio's
  Test Collector (if you target a WSAD build).

Note that there is a _lot_ more work remaining--we only have fixtures
for a tiny fraction of workbench Resources (e.g. to create projects
with a given nature and containing given artifacts) and scenarios
(e.g. to setup a given configuration of pages)--so we are actively
seeking IBMers (since we're currently only in IIOSB) who would like to
use abbotforswt to automate FVT of their own UIs. We can help you code
the fixtures and testers you will need; in return, we could add that
code to the repository, and help grow the project.


If you would like to help us develop or document, please send me an email!

Back to abbotforswt home

Back to abbotforswt project page


Tom Roche, WebSphere Studio Model2 Tooling