Monday, July 27, 2009

Automating Unit tests for RCP applications with the Eclipse Test Framework

The initial article that help me in getting my JUnit test to be run automatically with the Eclipse Test Framework can be found on the RCP quickstart site.

The article, the example as well as the comments where very helpfull but not sufficient enought to answer my needs that is why I wanted to publish some of my findings on this blog.
All the following discussion will be base around this piece of ant script:

<ant target="ui-test" antfile="${library-file}" dir="${eclipse-home}">
  <property name="os" value="${baseos}"/>
  <property name="ws" value="${basews}"/>
  <property name="arch" value="${basearch}"/>
  <property name="data-dir" value="${mhdk.root.for.test} -clean -testApplication com.nds.france.mhdk.mhdkmanager.rcp.application" />
  <property name="plugin-name" value="test.all.test.suite" />
  <property name="classname" value="com.nds.test.AllTests" />

This is a cut and paste from Patrick Paulin's example but I removed the emma reference as I am only interested in the unit tests.
What I did, as many of you might have done, was to test the example and I could get it running quickly then I adapted it for my own RCP application.

1) -cleanYou may have noticed that the data-dir property is set to a path and ends with -clean.
   <property name="data-dir" value="${mhdk.root.for.test} -clean" />

Actually this is the only way to pass extra parameter(s) to the eclipse application and I incidently removed it as I did not see the reason for it being here.
Do not do that !!!, I ended up with a java.lang.NoClassDefFoundError: junit/framework/TestListener and spent some time figuring this out.
I have not yet understoud why this is compulsory but this does not work otherwise.

2)RCP application test
The way the script is written does not actually execute your RCP application, but rather launch the org.eclipse.test.coretestapplication application that will load your plugin and run the test class specifyed as plugin-name.You may change the target attribute if you want to perform graphical tests that require a workbench to be created using the value : ui-test, this will launch the org.eclipse.test.uitestapplication.
But what if your application does some specific initialisation when it is started, like mine that uses the workspace (-data) as a specialzed area for accessing data?
If you need your application plugin Activator or your application class to be called before the unit test starts you may then extend the data-dir value with -testApplication such as:

<property name="data-dir" value="${my.workspace} -clean -testApplication">

3) debug all this
If you want to debug your test while launching them using the ant script or even want to debug the test framework just to see what happens you can always add the following property to the task that launches the unit test.
<property name="extraVMargs" value="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=1716">

This will start the eclipse wirtual machine and stop right before the first byte code is executed waiting for a debugger connection to attach to the process.
Go to the Debug dialog box in Eclipse and create a new Remove Java Application configuration with the following parameters.
Connection type : Standard(Socket Attach)
Host : localhost
Port : 1716 (identical to the one in the extraVMargs property)

You may have to configure the source tab if you want the debugger to display the source code of your application or of the Eclipse Test Framework.

4) No space in folders name
Last but not least...
Do NOT use spaces in folder's name, the Eclipse Test Framework and scripts do not like them at all and it took me some time to figure this out.

That is for now, I hope that sharing of my experience will help other people automating their unit test with RCP applications.