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
@SuppressWarnings("unchecked")
public void testDoSomethingInterestingWithEclipse() throws Exception {

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


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


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

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




}

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

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

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

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