About Me

My photo
I'm project manager of a software development team at www.researchspace.com. I've been developing bioinformatics software for the last 9 years or so, and I'm hoping to share some of the experience and knowledge I've gained with Eclipse RCP, Java web app development and software development in general on these blogs.

Thursday, 2 October 2008

SWTBot - gui testing for RCP?

I've been looking for a GUI testing tool for Eclipse RCP for a while with little success - open source solutions tend to have astepp learning curve while commercial tools such as Squish or WindowTester I've never got to work properly.

Today I've been looking at SWTBot which looks really promising. It provides complete access to the underlying SWT widgets, has certain Eclipse specific methods for accessing views and editors,
and can be run just like a regular JUnit test.

I'm just getting started with a new project that is currently just a single plugin.
To create tests using SWTBot, I created a new regular plugin project that depends on my RCP project and the SWTBot plugins. By putting the tests their own plugin it avoids my own project having dependencies on SWTBot and other transitive dependencies such as JDT.

Running the tests couldn't be easier - write a test case extending SWTBotEclipseTestCase
and add your tests.

My first test tests my own new project creation wizard - here is the code for it:

public class testSWT1 extends SWTBotEclipseTestCase {
// stuff you can do with Eclipse
public void testDoSomethingInterestingWithEclipse() throws Exception {

bot.menu("File").menu("New Wizards").menu("Other...").click();
assertEnabled(bot.button("Next >"));
bot.button("Next >").click();

bot.shell("New SBSI Project").activate();

assertFalse(bot.checkBox("Butt1").isChecked()); // default
bot.label("Project name: ").getText();

SWTBotText text = bot.text("");
assertTrue(canFinishWithName(" NAME",text));// trailing space OK
assertFalse(canFinishWithName("N AME",text));


private boolean canFinishWithName(String name, SWTBotText text) throws WidgetNotFoundException,
InterruptedException {
return bot.button("Finish").isEnabled();

private void selectSBSINewProjectWizard() throws WidgetNotFoundException {
SWTBotTree tree = bot.tree();
SWTBotTreeItem item= tree.getTreeItem("SBSI");

SWTBotTreeItem item2 = item.getNode("New SBSI Project wizard");

This test navigates the standard Eclipse New-> dialogs and then tests a creation wizard's ability to finish based on the name typed in.

What I particularly like are:
  1. It's expressive
  2. It will be straightforward to write helper classes for more complex widgets like wizards
  3. It runs in real time so you can see what's going on.
One thing to note is that widgets are identified by their text or title rather than any concept of ID. Therefore you need to be careful to get the name right, especially with spaces.

Also, I came a cropper with bot.button("name") for a checkbox. Whilst a checkbox is a Button type inSWT, SWTBot has its own method bot.checkbox("name") which must be used instead.

Some mysteries remain - how to access a context menu for a view when you don't know its name?

Thanks for reading


Ram said...

A good place to ask your questions would be the SWTBot discussion lists (http://swtbot.sourceforge.net/mail-lists.html).

KetanPadegaonkar said...

I'm happy that you've liked SWTBot so far :)

Some mysteries remain - how to access a context menu for a view when you don't know its name?

I do not understand the intent of right clicking on a view who's name you do not know. I'm surely missing something obvious here, and would like to hear from you. I'm available on the mailing list that Ram has pointed out: http://swtbot.sourceforge.net/mail-lists.html

Anonymous said...

i spended hours of hours triing to expanding a tree...

Nick said...

Well what if you are unfamiliar with the software code, and you merley find a context menu with "Update CTRL+U" you have no clue how the string will match, if its all spaces, if its tabs, "Update" does not match, and your left wasting your time. It simply should have an array of first item, second item etc, so then this is not necessary and is more intuitive.