Dimitri Missoh
enthusiastic technologist and problem solver

February 15th, 2009

Nuts and bolts of the UI development: GUI Test of SWT and Eclipse Applications

To be honest, I’m not the programmer I’ve dreamed to be, the one that has 100% of his code test covered. As a GUI developer I had an excuse in the past, namely that there are no acceptable GUI testing frameworks one can rely on (open source and suitable for eclipse RCP Application). I tried some of them but wasn’t very happy:

Until the day I’ve found the SWTBot library developed by Ketan Padegaonkar. This library still under development but can already be used to write professional functional test for SWT and eclipse based applications. The API is simple, intuitive but powerfull. This framework has such a success, that in the meantime there is a proposal to move it to the eclipse.org foundation.

This tutorial describes step by step how to configure your IDE to be able to test your first RCP application. I hope that this warm-up will encourage beginners to adopt, put into practice and understand the importance of GUI testing in their daily work.

So let’s start:

System requirement:

  • The Java JRE 5.0 is installed on my PC
  • and I’am using the Eclipse IDE for Plug-in developer (Ganymed - version 3.4 SR1)

Step 1 - Installing SWTBot

  • Start your eclipse IDE and choose [Help/Install New Software...]
  • Than click Add Site and enter the following URl for the updatesite: http://swtbot.sourceforge.net/download.html. Than [OK]. You can also download the plug-ins directly if you prefere. See the SWTBot webpage for more details.
  • Select “SWTBot Eclipse Feature” and “SWTBot SWT Feature” and install them (your probably need to restart the workbench).

Step 2 - Download the Apache commons collection library

Since SWTBot depends on this library, it should be dowloaded and added in the next steps to the classpath.

Step 3 - Create the RCP application under test

  • We use the Mail Sample delivered with the IDE as the project under test. To create this project simple choose [File/New/Project/Plug-in Project] and enter the name “com.dmissoh.rcp.mail” or any name of your choice.
  • Access the next wizard page by clicking on next. In the “Plug-in options” group check the options “Generate an activator….” and “This plug-in will make contribution to the UI“.  Then check the option yes that corresponds to the question “Would you like to create a rich client application?
  • Choose “RCP Mail Template” on the next wizard page, and terminate with [Finish].

Step 4 - Create the test plug-in

  • As described in step 3 create a new plug-in project using [File/New/Project/Plug-in Project]
  • Do not use any template for this project
  • Name it “com.dmissoh.rcp.mail.test
  • Use the context menu on this project and add a the new folder “lib” as shown in fig. 1
  • Use the context menu on this project and add a the new folder “config
  • In the ‘config’ folder create a new file named log4j.properties and fill it with the content of the snippet below:
    log4j.rootCategory=DEBUG, R, O
    # Stdout
    # File
    # Control the maximum log file size
    # Archive log files (one backup file here)
    log4j.appender.R.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n
    log4j.appender.O.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n
  • Copy the jar file “commons-collections-3.2.1.jar” you previously unzip in step 2 into this “lib” folder.
  • Go the the plugins folder of your eclipse IDE (e.g. under “C:\Programme\eclipse3.5\eclipse\plugins”), and copy the following jars into the “lib” folder: net.sf.swtbot.eclipse.finder_1.2.0.921.jar, net.sf.swtbot.eclipse.spy_1.2.0.921.jar, net.sf.swtbot.eclipse.ui_1.2.0.921.jar, net.sf.swtbot.finder_1.2.0.921.jar as shown in fig.1.
  • Double click on the file “META-INF/MANIFEST.MF” of the project “com.dmissoh.rcp.mail.test”, select the tab “runtime” and use the “Add…” button to add the five jar that we’ve copied into the lib folder of this project. At the end, it should look like on fig. 2.
  • We now need to add some dependencies to our test plug-in. Click on the MANIFEST.MF file located in the META-INF folder of the test plug-in org.dmissoh.rcp.mail.test and open the tab Dependencies. Use the Add button to add both org.apache.log4j (bundle-version=”1.2.13″) and org.junit (bundle-version=”3.8.2″) to the dependencies. Fig. 3 show how it should looks like.

P.S.: This is the quick and dirty way to add third party jars into your project. It is always better to add all the jar file your project depends on in a another plug-in, and add this library plug-in as a dependency to your main plug-in.

Figure 1 - Project structure in the eclipse IDE

Figure 2 - The classpath after jars have been added.

Figure 3 - Project Dependencies

Step 5 - Writing the test class

It is now the time to write the test case.

  • Use the context menu on the ’src’ folder of the ‘org.dmissoh.rcp.mail.test’ plug-in project to add the new package org.dmissoh.rcp.mail.test
  • In this package create a new class RcpMailTestCase and fill it with the snippet below. P.S.: This Test Case class should extends the SWTBotEclipseTestCase. As you can see, this test cases checks the some of the basic functionalities the mail RCP application contains like the tree viewer and the about dialog.

package org.dmissoh.rcp.mail.test;
import net.sf.swtbot.eclipse.finder.SWTBotEclipseTestCase;
 * A test case to run some basic unit tests on the Mail RCP sample.
 * @author Dimitri Missoh.
public class RcpMailTestCase extends SWTBotEclipseTestCase {
	 * Test the about dialog
	 * @throws Exception
	public void testAboutDialog() throws Exception {
		 * Check that we can open the about dialog,
		 * the plug-in details dialog and
		 * the configuration details dialog.
		 * */
		bot.menu("Help").menu("About RCP Product").click();
		bot.button("Plug-in Details").click();
		bot.button("Configuration Details").click();
	 * Test the dialog and the corresponding menu's command
	 * @throws Exception
	public void testDialog() throws Exception {
		 * Try to open the dialog using the menu.
		 * This is a way to make sure that this menu option is available.
		 * Also make sure that the dialog can be closed
		 * */
		bot.menu("File").menu("Open Message").click();
	 * Test the navigation tree
	 * @throws Exception
	public void testTree() throws Exception {
		 * Now we try to navigate the tree.
		 * Make sure that the first tree node has 3 children
		 * */
		assertEquals(1, bot.tree().getTreeItem("me@this.com").getNodes().size());
		assertEquals(3, bot.tree().getTreeItem("me@this.com").getNodes().size());
		 * Make sure that the second tree node has only one child
		 * */
		assertEquals(1, bot.tree().getTreeItem("other@aol.com").getNodes()
		assertEquals(1, bot.tree().getTreeItem("other@aol.com").getNodes()
	 * Test view related functions
	 * @throws Exception
	public void testView() throws Exception {
		 * Check that we have only two view opened on start:
		 * - the message view
		 * - the navigation view
		 * Than open one additional message view and check that we have one view more.
		 * At the end we close both message view and make sure that we have only one view left
		 * i.e. the navigation view.
		assertEquals(2, bot.views().size());
		bot.menu("File").menu("Open Another Message View").click();
		assertEquals(3, bot.views().size());
		assertEquals(1, bot.views().size());

Step 6 - Running the test

Running the SWT bot test is as simple as running a classic JUnit test. Expect that we have to set the path to the log4j.configuration file in the corresponding Debug Configuration Dialog.

  • Click right on the RcpMailTestCase class in the package explorer and select [Run As/SWTBot Test], which is a new entry that should appears if the SWTBot feature as been successfully installed as described in Step - 1.
  • The test run will failed because the the path to the Log4J configuration file is missing.
  • Select from the menu [Run/Debug Configurations...] to open the debug configuration dialog
  • Select the corresponding SWTBot test (I’v called it MailTest)
  • In the Test-Tab select JUnit 3
  • In the Main-Tab select org.dmissoh.rcp.mail.product under [Program to Run/Run a Product:]
  • In the Arguments-Tab add the following entry to VM Arguments as shown on fig. 4:

Figure 4 - Debug Configuration

If all test runs without failure you should see the pleasant JUnit green bar at the end.

For those who are interested in the use of JUnit in general for RCP and OSGi applications, the following blog entries can be useful:

In his article Running Unit Tests for RCP and OSGi Applications, Patrick describes how sets of tests across multiple plug-ins or fragments can be run without using test suites. In one of his previous articles (Testing Plug-ins with Fragments) he explains how fragments can be used to separate the test code from the business code.

Download Projects Files.

January 25th, 2009

Interested in any key events of an SWT Application?

There is actually a way to achieve that. In an appropriate location of your code add:

Display.getDefault().addFilter(SWT.KeyDown, listener);

where the listener to implement can look like:

Listener listener = new Listener() {
   public void handleEvent(Event event) {
      // do some amazing things with the event

Don’t forget to unregister your listener on dispose.