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.

Monday, 5 April 2010

Headless SWTBot testing for the Eclipse RCP mail example project

Introduction
Today I'm going to describe the steps needed to run the SWTBot functional tests headlessly. Although there is some documentation on the SWTBot wiki pages I've not found a complete example using a simple project such as the RCP Mail client example project.



The aim of this tutorial is to demonstrate how to set up headless SWTBot test for the RCP mail application. I am no expert in this, but I thought it might be useful to provide a set of instructions using an example that everyone can access, at least to get a working example to begin with. To be able to follow this tutorial it is best if


  • You have some experience using SWTBot in the Eclipse IDE
  • You have some knowledge of Ant builds and Eclipse PDE builds.


This tutorial is based on input from several sources : from Ralf Ebert's tutorial blog on p2 builds , from Kai Toedter's mp3 client demo RCP app , and Ketan Padegaonkar's SWTBot tutorial at EclipseCon 2010 and the SWTBot wiki pages.


The main steps in this tutorial are

  1. Create an RCP mail application and feature.
  2. Develop a headless build for the RCP mail app.
  3. Develop an SWTBot based test plugin to test the UI of the mail app
  4. Develop a headless build and execution of the SWTBot tests.


Set up:


This tutorial is set up using Eclipse 3.5.2. You will need two copies of Eclipse, one as your IDE and one as a target to compile against. The target should contain the RCP delta pack , and the full PDE feature set. Both Eclipses should have SWTBot installed (best done through the update site). This tutorial uses Galileo, I've not checked with Helios or Ganymede if this works. The Galileo update site is available at http://download.eclipse.org/technology/swtbot/galileo/dev-build/update-site.

All the projects are available in zipped workspace here






Step 1 : Create RCP mail application:


This takes several stages: create the RCP app, create a product, create a feature,

and do an export build using features.

a ) Create RCP app

Switch to a clean empty workspace

  • Set your target Eclipse to be the Eclipse into which you've installed the RCP delta pack.

  • Create a new plugin project called 'mail'. Make sure you have chosen that it is an RCP application(Pic).
  • Choose 'RCP Mail Template' as the example template. Otherwise accept all defaults.




CHECKPOINT :Select the newly created mail project, right-click Run As-> Eclipse Application - it should run!


b) Create a product file

Now we're going to create a product file for our mail application.

Select the mail project, right-click and choose 'New Product Configuration' and in the ensuing dialog call the product file 'mail.product' . Click Finish.





c) Now we're going to create a feature for the mail project. Click New->Feature Project,

call it 'mail.feature' and in the subsequent page add the 'mail' plugin (Picture below). Click Finish.





d). Now, go back to the product configuration file you created in step b) and open it in the the Product editor. In the overview tab, change the 'This project configuration is based on:' from plugins to features. Now click on the dependencies tab and add the following 2 features

  • org.eclipse.rcp
  • mail.feature





CHECKPOINT:

Go back to the overview tab, click 'Synchronize with defining plugin', and 'Launch an Eclipse app' - it should still run! At this stage you can try a product export from the overview page; just accept the defaults and you should get an exported functional RCP app.

So, at this stage we have a product configuration that has all the required functionality to export a working RCP mail application.


Step 2 Creating a headless ant build for the mail client:


First of all, create project 'mail build' and copy in these 2 files:

build.properties

build.xml.

To get the headless build to work on your machine, you will need to edit some file paths and platform specific settings in 'build.properties'. These are documented at the start of the file.

Build.xml can remain unchanged.


Checkpoint: you can now run the 'Build from workspace' ant target and get a build generated into a folder called user.home/MailBuilds/Builds/I.RCPMail. Unzip the archive and check the application runs.


Step 3: Now we'll finally get round to working with SWTBot!!


Create a new, standard plugin project called 'testMail'. Add the following plugins to the list of required plugins in the 'Dependencies' section:




org.junit4

org.eclipse.swtbot.eclipse.finder

org.eclipse.swtbot.swt.finder

org.hamcrest


Now create a testcase called MailApplicationTest in package 'test' with some SWTBot tests; here is a sample below:



package test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.List;

import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.SWTBot;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.junit.Test;

public class MailApplicationTest {

private SWTWorkbenchBot bot=new SWTWorkbenchBot();

@Test
public void testApplicationWindow ()throws Exception{
assertNotNull(bot.shell("RCP Product"));
}

@Test
public void testOpenAnotherView ()throws Exception{
SWTBotMenu file = bot.menu("File").menu("Open Another Message View");
file.click();
List views = bot.views(WidgetMatcherFactory.withPartName("Message"));
assertEquals(2, views.size());
views.get(1).close();
}

@Test
public void testOpenMessage ()throws Exception{
SWTBotMenu file = bot.menu("File").menu("Open Message");
file.click();
bot.shell("Open").bot().button("OK").click();
}

@Test
public void testClickMessageLink ()throws Exception{
SWTBot viewBot = bot.viewByTitle("Message").bot();
viewBot.link("nicole@mail.org").click();
SWTBotShell shell = bot.shell("Not Implemented");
shell.bot().button("OK").click();
}

@Test
public void testNavigationView ()throws Exception{
SWTBot viewBot = bot.viewById("mail.navigationView").bot();
String node = viewBot.tree().expandNode("me@this.com").getNodes().get(0);
assertEquals(node, "Inbox");
}
}


Now check the tests run by configuring a new SWTBot launch configuration:

Choose 'mail.product' as the product to launch. You may need to go into the 'plugins' tab and 'add required plugins' if the app fails to launch.


Below are screenshots needed to get the launch configuration to work:





















CHECKPOINT: You can run the SWTBot tests successfully in the IDE, 5 tests should pass.


Step 4 Finally we're ready to run the tests from an Ant script!!

a) First of all create a new 'General' project called 'mail.test.build' and copy into it the build.xml and build.properties from the mail.build project. We'll come back to these later.


b) Now create a feature for your test plugin. Create a new Feature project called 'testMail.feature' and add the testMail SWTBot test plugin as its single component plugin.



c) In the testMail plugin, create a new product configuration and call the product file 'testMail.product', and make it a feature based product. This product will contain the features needed for the mail app, as well as those needed for SWTBot. The end result is that , when exported, SWTBot and its dependencies will be 'embedded' in the RCP app. So add the following features to the product:

  • mail.feature
  • org.eclipse.rcp (these were needed for our app)
  • testMail.feature (our SWTBot test feature)
  • org.eclipse.swtbot
  • org.eclipse.swtbot.eclipse
  • org.eclipse.swtbot.eclipse.test.junit4 (the swtbot features)
  • org.eclipse.pde
  • org.eclipse.jdt
  • org.eclipse.platform ( dependencies for SWTBot)



CHECK: In the testMail.product configuration overview tab, following a 'synchronize with product's defining plugin' and launching, the test product should launch. Also, an export of the product should proceed successfully (using the Eclipse product export wizard). At this point we don't need the tests to run, we just want to make sure that the app still runs OK


d) Create a headless build of the SWTBotted- mail application. In the mail.test.build project we created in step a), we just need to make a few alterations so it will build our test project:

In build.properties, change the 'product' property to

 product=${buildDirectory}/plugins/testMail/testMail.product
In build. xml, add the lines :

<include name="testMail*/**" />
<exclude name="testMail*.feature*/**" />
<include name="testMail.feature*/**" />


into the copyProjectsFromFilesystem target

so that it looks like this :


<target name="copyProjectsFromFilesystem">
<mkdir dir="${buildDirectory}" />
<mkdir dir="${buildDirectory}/plugins" />
<mkdir dir="${buildDirectory}/features" />
<copy todir="${buildDirectory}/plugins">
<fileset dir="${sourceDir}">
<include name="mail*/**" />
<include name="testMail*/**" />
<exclude name="*mail*.feature*/**" />
<exclude name="testMail*.feature*/**" />
</fileset>
</copy>
<copy todir="${buildDirectory}/features">
<fileset dir="${sourceDir}">
<include name="mail.feature*/**" />
<include name="testMail.feature*/**" />
</fileset>
</copy>
</target>


This just ensures we will include the new test features and plugins in the headless build as well.

The build should just run in the same way as for the standard RCP headless app that we performed in stage 2.


CHECKPOINT: Unzip the build and verify that the exported 'Test' build starts properly.


e) Now invoke the tests using an ant task provided by SWTBot as described in the SWTBot wiki . To begin with you can create

a file called 'SWTBottest.xml' in your IDE eclipse and paste in the content below; in real usage you would probably want this to to merged

in with your standard build and invoked automatically after the build has finished.


This task is provided verbatim here and you will need to edit the property

'eclipse-home' to point to your RCP app install.

You may need to alter some of the other properties, for example those concerning your OS, or the SWTBot build IDs. For the RCP mail application, if you have named the projects and artifacts the same as me, you won't have to alter the plugin-name, classname, testProduct or plugin-name properties.


<project name="testsuite" default="run" basedir=".">

<!-- Edit this to be the path to your exoprted RCP application -->
<property name="eclipse-home" value="/Users/radams/MailBuilds/BUILDS/I.RCPMail/RCPMail" />

<!-- The SWTBot build ID (look in plugins/ to see if this is different) -->
<property name="all.buildId" value="2.0.0.512-dev-e35" />

<!-- The OS running the tests -->
<property name="os" value="macosx"/>
<property name="ws" value="cocoa"/>
<property name="arch" value="x86"/>

<!-- Edit this to be the name of your test plugin -->
<property name="plugin-name" value="testMail" />
<property name="classname" value="test.MailApplicationTest"/>
<property name="testProduct" value="mail.product"/>
<!-- path to library file ( which should be included in your RCP app) -->
<property name="library-file" value="${eclipse-home}/plugins/org.eclipse.swtbot.eclipse.junit4.headless_${all.buildId}/library.xml"/>

<!--- Don't need to edit below this point -->
<target name="suite">

<condition property="jvmOption" value="-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts">
<os family="mac"/>
</condition>

<property name="jvmOption" value=""></property>

<property name="temp-workspace" value="workspace" />
<delete dir="${temp-workspace}" quiet="true" />

<!-- remove junit3 fragment -->
<delete dir="${eclipse-home}/plugins/org.eclipse.swtbot.eclipse.junit3.headless_${all.buildId}" />
<delete dir="${eclipse-home}/plugins" includes="org.eclipse.swtbot.ant.optional.junit3_${all.buildId}.jar"/>

<ant target="swtbot-test" antfile="${library-file}" dir="${eclipse-home}">
<property name="data-dir" value="${temp-workspace}" />
<property name="testProduct" value="${testProduct}" />
<property name="plugin-name" value="${plugin-name}" />
<property name="classname" value="${classname}" />
<property name="vmargs" value=" -Xms128M -Xmx368M -XX:MaxPermSize=256M ${jvmOption}" />
</ant>
</target>

<target name="cleanup" />

<target name="run" depends="suite,cleanup">
<ant target="collect" antfile="${library-file}" dir="${eclipse-home}">
<property name="includes" value="*.xml" />
<property name="output-file" value="${plugin-name}.xml" />
</ant>
</target>

</project>



Now invoke the build - you should the app fire up and the application respond to the tests. You should now be able to follow the results as described in the Eclipse wiki page on SWTBot.


Summary

In this blog I've tried to give a complete run-through of all the steps needed to get headless SWTBot tests running for an Eclipse RCP. A complete workspace of the projects is available here which hopefully will give interested readers further clarification on details.

Thanks very much for reading - I hope this is of some use.





17 comments:

KetanPadegaonkar said...

Thanks for the very useful and complete summary :)

Just one input though: some of the ant XML on the blog is something that could use some cleanup. It seems that blogger has gobbled up some xml thinking it is html.

I'm also curious if you'd be interested in contributing your sample test plugin to the swtbot project. That way the example project is available as a download from the eclipse download site for a lot of other people to see!

Thanks!

- Ketan

otter606 said...

Would be very happy to contribute text and sample project.
Editing on blogger for code /xml markup is not ideal; I'll see what I can do but would probably look better on the Eclipse wiki :)

Ralf Ebert said...

Hi Richard,

thanks for the well-done description!

What happens if you exclude the PDE/JDT features from your feature? These shouldn't go into the product, except you're writing a Mail application with integrated Java development environment :)

I would also love to see this as an official example, are you aware of http://github.com/ketan/swtbot/tree/master/examples/rcp/ ? It would be great to add a headless build to that example; if you want to contribute these, I'd be glad to help you, don't hesitate to ask me if you encounter any problems.

otter606 said...

Hi Ralf,
Thanks for the comments - you are very welcome to download the example projects and include them with SWTBot examples.

I've rewritten the tutorial in Textile format (having just discovered MylynWikiText at EclipseCon) and you are very welcome to that as well if you like.
Drop me a line at firstname.surname@ed.ac.uk and I'll reply with the attachment.

Regarding the JDT/PDE/workbench dependencies - if for example I remove the org.eclipse.jdt feature, it all compiles fine but when the tests do not run - the report says 0 tests run. When I add the org.eclipse.jdt feature back and rebuild it runs fine.

So this could conceivably be a problem e.g., if you have tests that depend on menus being at an exact index etc., since the JDT adds in menu items. Alternatively I'm invoking the tests incorrectly somehow.

Partner Profiles said...

Interesting post. Thanks for sharing this and for giving us screen shots as well. You did an awesome work with this blog post.

Anonymous said...

Could you please check up the download links of build.xml and build.property please. They are not there anymore. :(

otter606 said...

I've uploaded the files -should be downloadable now.
Cheers
Richard

Sang-Sin said...

Thanks for detailed explanations!
But, links of build.xml and build.property were broken.
Could you check this?

Amit Mittal said...

hi... thanks for the detailed steps.
the workspace download link which takes you to the file hosting service is not working. it says file not found. can you please upload at some other place.

otter606 said...

I've updated the links again to build.properties and the workspace.

bnolte said...

The links are dead again for the build.xml and the rollup package listed at the end. May I suggest some other download service?

shan said...

It is very useful and I really want to have a try. But I fail to get those uploaded files. Could you please update the links? Thanks a lot.

Tom Brus said...
This comment has been removed by the author.
Tom Brus said...

hi... thanks for this, but the workspace download link is not working. it says file not found. can you please upload somewhere else or re-upload. Thanks!

Anonymous said...

Wonderful article for getting start with SWTBot!
However, the download link is not available again...Could you paste the build.properties and build.xml? Thank you very much.

Abhishek Singh said...

links for build.xml and build.properties are no accessible. Please upload those files again.

SÅ‚awomir Zakrzewski said...

I would ask to update links, because build.xml and build.properties are not accessible.