| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> |
| <head> |
| <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>Automating Eclipse PDE Unit Tests using Ant</title> |
| <link href="../article.css" rel="stylesheet" type="text/css"> |
| <body> |
| <h1>Automating Eclipse PDE Unit Tests using Ant</h1> |
| <div class="summary"> |
| <h2>Summary</h2> |
| <p>This article outlines how to integrate your PDE unit tests into |
| an Ant based automated build, using a simple Eclipse plug-in as an |
| example, some simple java classes, basic Eclipse plug-in techniques and |
| some standard Ant tasks.</p> |
| <div class="author">By Brian Joyce, <a target="_blank" |
| href="http://www.duolog.com">Duolog Technologies Ltd., Galway, |
| Ireland</a></div> |
| <div class="copyright">Copyright © 2008, Brian Joyce</div> |
| <div class="date">June 13, 2008</div> |
| </div> |
| |
| <div class="content"> |
| <h2><a name="Introduction"></a>Introduction</h2> |
| <p>It's generally accepted that writing tests as part of software |
| development is a very good thing indeed. It's also generally accepted |
| that automating the running of tests in an automated or nightly build is |
| good engineering practice. Let's face it, if tests are not run |
| automatically then there's a good chance they won't be run at all, and |
| tests that are not run are next to useless.</p> |
| |
| <p>The Eclipse Plug-in Development Environment (PDE) provides a |
| excellent framework for developing plug-ins and also provides facilities |
| to write and run PDE unit tests for your plug-ins that can be run from |
| within the Eclipse environment.</p> |
| |
| <p>Once you have taken the time and effort to write these valuable |
| PDE unit tests, how do you automate the running of these PDE unit tests |
| so that you can integrate them into your automated build?</p> |
| |
| <p>Searching the web provides several options for automating PDE |
| tests such as: </p> |
| |
| <ul> |
| <li>Markus Barchfeld's excellent <a |
| href="http://www.eclipse.org/articles/Article-PDE-Automation/automation.html" |
| target="_blank">Build and Test Automation for plug-ins and |
| features</a> article which details setting up automatic building and |
| testing for an Eclipse plug-in using the Eclipse headless build.</li> |
| <li><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.test/testframework.html?view=co" |
| target="_blank">Eclipse Test Framework</a>.</li> |
| <li>Patrick Paulin's RCP Quickstart post on <a |
| href="http://rcpquickstart.wordpress.com/2007/08/06/running-automated-tests-with-pde-build/" |
| target="_blank">Running Automated Tests with PDE Build.</a></li> |
| <li>Some more excellent links can be found at <a |
| href="http://eclipsenuggets.blogspot.com/2007/09/6-great-links-for-eclipse-build.html" |
| target="_blank">6 Great Links for Eclipse Build Automation with |
| PDE Build</a>.</li> |
| </ul> |
| |
| <p>As you can see writing PDE Tests can be complex, running PDE |
| Tests from the command line can be complex too, but running them and |
| collecting the results in a format that can be easily interpreted (e.g. |
| Junitreport format) is even more difficult.</p> |
| |
| <p>This article provides a detailed example application, the |
| enabling technology to collect and format test results (see <a |
| href="#PDE_Test_Utilities">PDE Test Utilities</a> ), and a build system |
| that demonstrates a generic mechanism for running PDE Tests using Ant, |
| allowing you to integrate it with any Ant build system.</p> |
| |
| <p>This PDE Test technique provides the following benefits:</p> |
| |
| <ol> |
| <li>Allows you to run your PDE Tests from the command line</li> |
| <li>Allows you to collect the PDE Tests results in a format that |
| can be easily interpreted (i.e. Junitreport format)</li> |
| <li>Allows you to integrate PDE Tests into any Ant-based build |
| system</li> |
| </ol> |
| |
| <p><strong>Note:</strong> all the techniques and examples detailed |
| in this article have been tested against Eclipse 3.3 (specifically |
| Eclipse 3.3.2 and 3.3.1.1) on Windows XP only and using <a |
| href="http://ant.apache.org/bindownload.cgi" target="_blank">Ant |
| 1.7.0</a> . There is also an <a href="PDETestExampleProjects-3.1.zip">Eclipse |
| 3.1 version</a> of the example code.</p> |
| |
| <h2><a name="Overview"></a>Overview</h2> |
| |
| <p>PDE unit tests are automated as follows:</p> |
| |
| <h3>Prerequisites:</h3> |
| |
| <ol> |
| <li>A dedicated PDE test Eclipse installation that is only used by |
| the automated build system.</li> |
| <li>For each Eclipse plug-in <i style="color: rgb(255, 0, 0);">A</i> |
| that is to be tested, an Eclipse plug-in fragment <i |
| style="color: rgb(255, 0, 0);">A-test</i> for <i |
| style="color: rgb(255, 0, 0);">A</i> that only contains the PDE unit |
| tests and their test dependencies for the plug-in <i |
| style="color: rgb(255, 0, 0);">A</i>.</li> |
| <li>A pre-defined (or specified) PDE test port.</li> |
| <li>A PDE test listener class to listen on the PDE test port for |
| the results from the PDE test run.</li> |
| <li>A list of PDE test classes to be run as part of the PDE Test |
| run</li> |
| </ol> |
| |
| <h3>Running the PDE unit tests:</h3> |
| |
| <p>See <a href="#Figure_1_-_Overview_diagram_of_the_PDE">Figure 1</a> |
| below for a visual representation of the PDE test steps.</p> |
| |
| <ol> |
| <li>Deploy plug-in <i style="color: rgb(255, 0, 0);">A</i> and |
| plug-in fragment <i style="color: rgb(255, 0, 0);">A-test</i> into a |
| pristine PDE test Eclipse installation.</li> |
| |
| <li>Select PDE test port (or use predefined reserved port).</li> |
| <li>Start the PDE test listener process that listens on the PDE |
| test port.Startup the PDE test Eclipse installation, specifying the |
| list of unit test classes to be run, and the PDE test port to output |
| test progress and results to.</li> |
| |
| <li>The PDE test Eclipse installation starts up and automatically |
| runs the specified tests and outputs the results to the PDE test port |
| where the PDE test listener process captures the results and outputs |
| them in standard Ant <a target="_blank" |
| href="http://ant.apache.org/manual/OptionalTasks/junit.html">junit</a> |
| task XML format.</li> |
| |
| <li>Run the regular Ant <a target="_blank" |
| href="http://ant.apache.org/manual/OptionalTasks/junitreport.html">junitreport</a> |
| task on the generated test results XML files.</li> |
| |
| <li>That's it: you now have a typical Ant JUnit HTML report |
| containing your PDE unit test results.</li> |
| |
| </ol> |
| |
| <div class="figure"><a name="Figure_1_-_Overview_diagram_of_the_PDE"></a><img src="images/PDETestProcessFlow.jpg" |
| style="border: 2px solid; width: 1121px; height: 610px;" |
| alt="PDE Test process flow diagram" |
| title="PDE Test process flow diagram"> |
| <p class="caption">Figure 1 - Overview diagram of the PDE Test steps</p></div> |
| |
| <h2>Prerequisites</h2> |
| |
| <p>This section describes the prerequisites for using this technique |
| in more detail.</p> |
| |
| <h3>Dedicated PDE test Eclipse installation</h3> |
| |
| <p>In order to run the PDE Tests you need a separate Eclipse installation |
| whose sole purpose is for running the PDE Tests. Having a dedicated |
| Eclipse installation provides a pristine and repeatable test environment |
| and avoids any possible conflicts or corruption that might occur with a |
| typical development Eclipse installation. </p> |
| |
| <h3>Use an Eclipse plug-in fragment for the PDE Unit Tests for a |
| plug-in</h3> |
| |
| <p>This technique promotes the use of <a |
| href="http://help.eclipse.org/help33/topic/org.eclipse.platform.doc.isv/guide/product_def_plugins.htm" |
| target="_blank">Eclipse plug-in fragments</a> to develop PDE Unit tests |
| for plug-ins, so for each Eclipse plug-in <i |
| style="color: rgb(255, 0, 0);">A</i> that is to be tested, an Eclipse |
| plug-in fragment <i style="color: rgb(255, 0, 0);">A-test</i> for <i |
| style="color: rgb(255, 0, 0);">A</i> that only contains the PDE unit |
| tests and their test dependencies for the plug-in <i |
| style="color: rgb(255, 0, 0);">A</i>.</p> |
| |
| <p>You can of course develop the PDE tests directly in the plug-in |
| (in a test directory), but this can lead to unwanted dependencies in |
| your plug-in and involves slightly more complicated packaging for |
| your plug-in (i.e. without test classes and test dependencies).</p> |
| |
| <p>The Eclipse plug-in fragment approach avoids these |
| pitfalls and although it requires a little more setup initially it |
| provides a cleaner and clearer mechanism for defining PDE Tests and also |
| provides a straightforward way for the build system of identifying which |
| plug-ins have PDE Tests associated with them.</p> |
| |
| <p>For a good description and more general discussion of using |
| Eclipse plug-in fragments for testing, see Patrick Paulin's RCP |
| Quickstart article <a |
| href="http://rcpquickstart.wordpress.com/2007/06/20/unit-testing-plug-ins-with-fragments/" |
| target="_blank">Testing Plug-ins with Fragments</a>.</p> |
| |
| <h3>PDE test port</h3> |
| |
| <p>In order for the PDE test runner and the PDE test listener |
| processes to communicate, both processes need to use a predefined or |
| specified port so that the PDE test runner can send the test progress |
| and results to the PDE test listener process. In the example code |
| we use a utility class <a href="#PDETestPortLocator"><code>pde.test.utils.PDETestPortLocator</code></a> |
| in the <a href="article.html#PDE_Test_Utilities">pde.test.utils</a> |
| plug-in to find an available port and this is used by the PDE test runner |
| and PDE test listener processes to communicate.</p> |
| |
| <h3>PDE test listener process</h3> |
| |
| <p>In order to be able to monitor and record the progress |
| and results of the PDE test run, you need a PDE test listener |
| process that listens on the specified port to collect PDE test progress |
| and results from the PDE test runner process. Ideally the PDE test |
| listener process should provide the results of the PDE test run in a |
| manner that is easy to interpret should any of the tests fail.</p> |
| |
| <p>The <a href="#PDETestResultsCollector"><code>pde.test.utils.PDETestResultsCollector</code></a> |
| class (using the <a href="#PDETestListener"><code>pde.test.utils.PDETestListener</code></a> |
| class) in the <a href="article.html#PDE_Test_Utilities">pde.test.utils</a> |
| plug-in, provides the PDE test listener process that listens on the |
| specifed port for test results from the PDE test runner process and |
| handles them using the <code>org.apache.tools.ant.taskdefs.optional.junit.JUnitTest</code> |
| and <code>org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter</code> |
| classes (available from Apache Ant API) to provide the results in the |
| same XML format that is output by the Ant <a target="_blank" |
| href="http://ant.apache.org/manual/OptionalTasks/junit.html">junit</a> |
| task. These XML result files can then be used by the Ant <a |
| target="_blank" |
| href="http://ant.apache.org/manual/OptionalTasks/junitreport.html">junitreport</a> |
| task to provide an <a href="reports/test/index.html">HTML report</a> of |
| the PDE test run that is very easily interpreted.</p> |
| |
| <p>For example to run the PDE test listener process from the command |
| line for our example PDE tests would similar to:</p> |
| |
| <pre> java -classpath ... pde.test.utils.PDETestResultsCollector PhoneBookExample-test 1623</pre> |
| |
| <h3>PDE test runner process</h3> |
| |
| <p>Eclipse provides a mechanism for running tests from the command |
| line using the main Eclipse launcher class to launch the <code>org.eclipse.pde.junit.runtime.uitestapplication</code> |
| application, this is the PDE test runner process. The PDE test runner |
| process is passed details of the port to publish test progress and |
| results to for listeners to analyse, the plug-in name being tested and |
| the names of the PDE test classes to run.</p> |
| |
| <p>For example to run the PDE test runner process from the command |
| line for our example PDE tests would similar to:</p> |
| |
| <pre>java -classpath ...\eclipse\plugins\org.eclipse.equinox.launcher_1.0.1.R33x_v20080118.jar |
| org.eclipse.equinox.launcher.Main |
| -application org.eclipse.pde.junit.runtime.uitestapplication |
| -data ...\PhoneBookExample-test\target\reports\test/output/ws |
| -dev bin |
| -clean |
| -port 1623 |
| -testpluginname PhoneBookExample |
| -classnames phonebookexample.dialogs.PhoneBookEntryEditorDialogTest</pre> |
| |
| <h3>PDE Tests classes list</h3> |
| |
| <p>The PDE test runner process takes as a parameter a comma |
| separated list of the test classes to run in a PDE test run. In the |
| example code, the name of the single test class to be |
| run is hardcoded i.e. <code>phonebookexample.dialogs.PhoneBookEntryEditorDialogTest</code> |
| but the generation of the list of PDE test classes could easily be |
| automated.</p> |
| |
| <h2>Running PDE Unit Tests in Ant</h2> |
| |
| <p>This section describes the Ant build file in the example code |
| that runs the PDE Tests and explains the key Ant targets involved. See <a |
| href="article.html#Figure_1_-_Overview_diagram_of_the_PDE">Figure 1</a> |
| above for a visual representation of the steps involved in running PDE |
| tests in Ant.</p> |
| |
| <p>The example code featuring full source and Ant build files |
| for a project containing PDE unit tests can be found in the |
| accompanying <a href="PDETestExampleProjects-3.3.zip">PDETestExampleProjects-3.3.zip</a> |
| ZIP file.</p> |
| |
| <p><strong>Note:</strong> that the <a |
| href="PDETestExampleProjects-3.3.zip">PDETestExampleProjects-3.3.zip</a> |
| ZIP file contains a full standalone project complete with an Ant |
| build system (see <a |
| href="article.html#PDETestExampleProjects.zip_Contents">zip |
| contents</a> below for more details). Unzip the contents into |
| a directory that is separate from your Eclipse installation and workspace.</p> |
| |
| <h3>Ant script that runs PDE Unit tests</h3> |
| |
| <p>The following Ant excerpt is from the Ant build file used to run |
| the PDE unit tests in the <i>PhoneBookExample-test</i> plug-in fragment |
| for the <i>PhoneBookExample</i> plug-in (see <i>projects\PhoneBookExample-test\build.xml</i> |
| in the accompanying ZIP file):</p> |
| |
| <pre><!-- Build file for the Phonebook Example plug-in PDE unit test fragment --> |
| <project name="phonebookexampletest" default="help" basedir="."> |
| ... |
| <target name="pde_test"> |
| <img src="images/tag_1.gif" align="middle" height="13" width="24"> <delete> |
| <fileset dir="${test.eclipse.dir}/configuration" includes="**/*" excludes="config.ini"/> |
| <fileset dir="${test.eclipse.dir}/plugins" includes="PhoneBookExample*.jar"/> |
| <fileset dir="${test.eclipse.dir}/plugins" includes="pde.test.utils*.jar"/> |
| </delete> |
| |
| <!-- Load plugin and pde tests plugin fragment into test eclipse installation --> |
| <img src="images/tag_2.gif" align="middle" height="13" width="24"> <copy todir="${test.eclipse.dir}/plugins" overwrite="true"> |
| <fileset dir="${published.plugins.dir}"/> |
| </copy> |
| |
| <delete file="pde_test_port.properties"/> <!-- properties file generated by PDETestPortLocator class in pde.test.utils --> |
| <img src="images/tag_3.gif" style="width: 24px; height: 13px;" |
| align="middle"> <java classname="pde.test.utils.PDETestPortLocator" fork="yes" classpathref="pde.test.port.locator.class.path"/> |
| <waitfor maxwait="10" maxwaitunit="second" checkevery="100" checkeveryunit="millisecond"> |
| <available file="pde_test_port.properties"/> |
| </waitfor> |
| <property file="pde_test_port.properties"/> |
| <echo message="Using port ${pde.test.port} for listening to PDE Test run"/> |
| |
| <parallel> |
| <daemons> |
| <img src="images/tag_4.gif" align="middle" height="13" width="24"> <antcall target="run_pde_test_listener"/> |
| </daemons> |
| <sequential> |
| <sleep seconds="5"/> <!-- Give the listener a few seconds to start up --> |
| <img src="images/tag_5.gif" align="middle" height="13" width="24"> <antcall target="run_pde_tests"/> |
| </sequential> |
| </parallel> |
| |
| <img src="images/tag_6.gif" align="middle" height="13" width="24"> <delete> |
| <fileset dir="${test.eclipse.dir}/plugins" includes="PhoneBookExample*.jar"/> |
| <fileset dir="${test.eclipse.dir}/plugins" includes="pde.test.utils*.jar"/> |
| </delete> |
| |
| <mkdir dir="${test.reports.dir}"/> |
| <img src="images/tag_7.gif" align="middle" height="13" width="24"> <move todir="${test.reports.dir}"> |
| <fileset dir="."> |
| <include name="**/TEST-*.xml"/> |
| </fileset> |
| </move> |
| </target> |
| |
| <img src="images/tag_4.gif" align="middle" height="13" width="24"> <target name="run_pde_test_listener"> |
| <java classname="pde.test.utils.PDETestResultsCollector" fork="yes" classpathref="pde.test.listener.class.path"> |
| <arg line="${plugin.name} ${pde.test.port}"/> |
| </java> |
| </target> |
| |
| <img src="images/tag_5.gif" align="middle" height="13" width="24"> <target name="run_pde_tests"> |
| <property name="test.classes.list" value="phonebookexample.dialogs.PhoneBookEntryEditorDialogTest"/> |
| <mkdir dir="${test.reports.dir}/output/ws"/> |
| <java dir="${plugin.dir}" classname="org.eclipse.equinox.launcher.Main" fork="yes" classpathref="equinox.launcher.class.path"> |
| <arg line="-application org.eclipse.pde.junit.runtime.uitestapplication -data ${test.reports.dir}/output/ws -dev bin -clean -port ${pde.test.port} -testpluginname PhoneBookExample -classnames ${test.classes.list}"/> |
| </java> |
| </target> |
| ... |
| </project></pre> |
| |
| <p>The key elements of this Ant build file are identified above:</p> |
| |
| <table cellpadding="2" cellspacing="2"> |
| <tbody> |
| <tr> |
| <td style="width: 10%;"><img src="images/tag_1.gif" |
| align="middle" height="13" width="24"></td> |
| <td style="width: 90%;">This prepares for the PDE test run by |
| deleting all previously deployed plug-ins from the plugins directory |
| of the dedicated test installation of Eclipse.</td> |
| </tr> |
| <tr> |
| <td style="width: 10%;"><img src="images/tag_2.gif" |
| align="middle" height="13" width="24"></td> |
| <td style="width: 90%;">This copies the set of plug-ins under |
| test (including the test fragment) into the plugins directory of the |
| test installation of Eclipse.</td> |
| </tr> |
| <tr> |
| <td style="width: 10%;"><img src="images/tag_3.gif" |
| align="middle" height="13" width="24"></td> |
| <td style="width: 90%;">This discovers an available port for the |
| PDETestListener to listen on - it does it by launching a simple java |
| class (PDETestPortLocator) to detect the next available port and |
| stores it as a property pde.test.port in the pde_test_port.properties |
| file. This property is then loaded from the pde_test_port.properties |
| file and is used in the test run.</td> |
| </tr> |
| <tr> |
| <td style="width: 10%;"><img src="images/tag_4.gif" |
| align="middle" height="13" width="24"></td> |
| <td style="width: 90%;">This step launches the PDETestListener |
| in a separate thread (using the Ant parallel & daemons tasks) to |
| listen for test results on the port identified by the pde.test.port |
| property (see Label 3 above)</td> |
| </tr> |
| <tr> |
| <td style="width: 10%;"><img src="images/tag_5.gif" |
| align="middle" height="13" width="24"></td> |
| <td style="width: 90%;">This is the actual step that runs the |
| PDE Unit tests and specified that the results should be published to |
| a listener using the port identified by the pde.test.port property |
| (see Label 3 above).<br> |
| Note: that the list of test classes needs to be specified for the |
| test run, this can easily be automatically generated.</td> |
| </tr> |
| <tr> |
| <td style="width: 10%;"><img src="images/tag_6.gif" |
| style="width: 24px; height: 13px;" align="middle"></td> |
| <td style="width: 90%;">After the PDE test run the test |
| installation of Eclipse is cleaned up by deleting all the deployed |
| plug-ins from the plugins directory.</td> |
| </tr> |
| <tr> |
| <td style="width: 10%;"><img src="images/tag_7.gif" |
| align="middle" height="13" width="24"></td> |
| <td style="width: 90%;">Copy the test results to a directory for |
| processing by the Junitreport Ant task.</td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <h2><a name="PDETestExampleProjects.zip_Contents"></a>PDETestExampleProjects-3.3.zip |
| Contents</h2> |
| |
| <p>The ZIP file contains 3 separate plug-ins (each with their own Ant |
| build.xml file) and an overall Ant build.xml file that coordinates the |
| build and test of the 3 plug-ins.</p> |
| |
| <table cellpadding="2" cellspacing="2"> |
| <tbody> |
| <tr> |
| <th>Contents</th> |
| <th>Type</th> |
| <th>Description</th> |
| </tr> |
| <tr> |
| <td>pde.test.utils</td> |
| <td>Plug-in</td> |
| <td>Provides the PDE test utilities used by Ant to run the PDE |
| unit tests, including the following classes:<br> |
| <ul> |
| <li>pde.test.utils.PDETestListener</li> |
| <li>pde.test.utils.PDETestPortLocator</li> |
| <li>pde.test.utils.PDETestResultsCollector</li> |
| </ul> |
| </td> |
| </tr> |
| <tr> |
| <td>PhoneBookExample</td> |
| <td>Plug-in</td> |
| <td>This is the main Eclipse plug-in PhoneBook example |
| application, including the following classes:<br> |
| <ul> |
| <li>phonebookexample.PhoneBookExamplePlugin</li> |
| <li>phonebookexample.actions.PhoneBookAction</li> |
| <li>phonebookexample.data.PhoneBook</li> |
| <li>phonebookexample.data.PhoneBookEntry</li> |
| <li>phonebookexample.dialogs.PhoneBookEditorDialog</li> |
| <li>phonebookexample.dialogs.PhoneBookEntryEditorDialog</li> |
| </ul> |
| <br> |
| For further details on the example application see <a |
| href="#Simple_Phonebook_Application">Appendix A</a> below.</td> |
| </tr> |
| <tr> |
| <td>PhoneBookExample-test</td> |
| <td>Plug-in Fragment</td> |
| <td>This is the Eclipse plug-in fragment for the PhoneBook plug-in |
| that contains the PDE unit tests for the PhoneBook GUI, including the |
| following test classes:<br> |
| <ul> |
| <li>phonebookexample.dialogs.PhoneBookEntryEditorDialogTest</li> |
| </ul> |
| <br> |
| For further details on PDE Unit tests for the example application see |
| <a href="#Example_PDE_Unit_Tests">Appendix B</a> below.</td> |
| </tr> |
| <tr> |
| <td>build.xml</td> |
| <td>Ant build file</td> |
| <td>Overall Ant build file, that provides targets that |
| coordinates the building and testing of the 3 plug-ins</td> |
| </tr> |
| <tr> |
| <td>readme.txt</td> |
| <td>Readme file</td> |
| <td>Provide basic information on how to run the example</td> |
| </tr> |
| <tr> |
| <td>project.properties</td> |
| <td>properties file</td> |
| <td>Specifies the target Eclipse and pde.test.utils versions |
| used in this project.</td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <h2><a name="PDE_Test_Utilities"></a>PDE Test Utilities |
| (pde.test.utils)</h2> |
| |
| <p>This plug-in contains a set of utilities that help automate the |
| running and monitoring of PDE Unit tests. </p> |
| |
| <h3><a name="PDETestPortLocator"></a>PDETestPortLocator</h3> |
| |
| <p>This class is responsible for discovering the next available port |
| on a system, creating a properties file called <i>pde_test_port.properties</i> |
| and writing a property called <i>pde.test.port</i> into the file and |
| setting it to the value of the next available port. This port is then |
| used by the Eclipse test runner process when publishing the progress and |
| results of tests and the PDE test listener process listens on the port |
| and processes the test results. </p> |
| |
| <h3><a name="PDETestListener"></a>PDETestListener</h3> |
| |
| <p>This class is responsible for listening on a specified port as an |
| Eclipse test listener and outputting the results of the test |
| run in the same XML format that is output by the Ant <a |
| target="_blank" |
| href="http://ant.apache.org/manual/OptionalTasks/junit.html">junit</a> |
| task. The test result XML files can then be |
| converted into an easily interpreted HTML JUnit report by the Ant <a |
| target="_blank" |
| href="http://ant.apache.org/manual/OptionalTasks/junitreport.html">junitreport</a> |
| task.</p> |
| |
| <h3><a name="PDETestResultsCollector"></a>PDETestResultsCollector</h3> |
| |
| <p>This class is responsible for starting the PDETestListener on the |
| specified port, for a PDE test run. The PDETestResultsCollector |
| process takes 2 parameters as follows: </p> |
| |
| <ol> |
| <li>PDE Test suite name - this is just a string that identifies |
| the PDE test suite name - usually the plug-in fragment name, e.g. |
| PhoneBookExample-test in our example code.</li> |
| <li>port number - specifies the port that the PDE test |
| runner process uses to publish PDE test progress and results, the PDE |
| test listener process listens on the port to process the test results.</li> |
| </ol> |
| |
| <h2>Conclusion</h2> |
| |
| <p>As stated in the introduction, there are several options available |
| for automating PDE tests; some more complex than others. The technique |
| detailed in this article provides another choice for build system |
| engineers. It delivers the following benefits: |
| </p> |
| |
| <ol> |
| <li>Allows you to run your PDE Tests from the command line</li> |
| <li>Allows you to collect the PDE Tests results in a format that |
| can be easily interpreted (i.e. Junitreport format)</li> |
| <li>Allows you to integrate PDE Tests into any Ant-based build |
| system</li> |
| </ol> |
| |
| <h2><a name="Simple_Phonebook_Application"></a>Appendix A: Example |
| Application - Simple Phonebook Application (PhoneBookExample)</h2> |
| |
| <p>The example application is a simple PhoneBook |
| application and some simple GUI PDE Tests. The aim of this article is |
| to show how you can integrate your PDE unit tests into an Ant build. In |
| consideration of this, the |
| example application and it's PDE unit tests have been deliberately kept |
| as simple as possible. </p> |
| |
| <p>The PhoneBook application is simple tool to store names and their |
| associated phone numbers. The application adds a simple "Phone" menu |
| item to the main menu as follows:</p> |
| |
| <p><img src="images/phonebook_menu.gif" |
| style="width: 718px; height: 350px;" alt="Image of phonebook menu item"> |
| </p> |
| |
| <p>Clicking on "Edit Phone Book" menu item causes the Edit PhoneBook |
| Dialog to be displayed:</p> |
| |
| <p><img src="images/phonebook_editor.gif" |
| style="width: 524px; height: 309px;" |
| alt="Image of PhoneBook editor dialog"></p> |
| |
| <p>Clicking on "New" button causes the Edit PhoneBook Entry Dialog |
| to be displayed:</p> |
| |
| <p><img src="images/phonebook_entry_editor.gif" |
| style="width: 523px; height: 298px;" |
| alt="Image of PhoneBook Entry Editor dialog"></p> |
| |
| <h3><a name="Making_GUI_Classes_testable_using"></a>Making GUI |
| Classes testable using package protection</h3> |
| |
| <p><img src="images/tip.gif" alt=""> Throughout the simple GUI |
| examples provided here, a deliberate style of making all |
| fields in GUI classes <em>package protected</em> has been followed. Making the |
| fields package protected allows the unit tests to access the GUI |
| components during a test run.</p> |
| |
| <p>For example, the local variables <img src="images/tag_1.gif" |
| align="middle" height="13" width="24"> are all package protected.</p> |
| |
| <pre>package phonebookexample.dialogs;<br>...<br>public class PhoneBookEntryEditorDialog extends TitleAreaDialog { |
| <img src="images/tag_1.gif" align="middle" height="13" width="24"> PhoneBookEntry phoneBookEntry; |
| <img src="images/tag_1.gif" align="middle" height="13" width="24"> Composite phoneBookEntryComposite; |
| <img src="images/tag_1.gif" align="middle" height="13" width="24"> Text nameText; |
| <img src="images/tag_1.gif" align="middle" height="13" width="24"> Text numberText; |
| ... |
| }</pre> |
| |
| <p>Note that this is not an ideal solution for making your GUI |
| classes testable, but it is simple and it works.</p> |
| |
| <h2><a name="Example_PDE_Unit_Tests"></a>Appendix B: Example PDE |
| Unit Tests (PhoneBookExample-test)</h2> |
| |
| <p>There is just a single PDE JUnit test class provided in the example |
| (PhoneBookEntryEditorDialogTest) and most of the tests there are pretty |
| straightforward, but there are a few tricks or techniques that do |
| require some further explanation. </p> |
| |
| <h3>Accessing the active shell</h3> |
| |
| <p><img src="images/tip.gif" alt=""> The active shell for your |
| GUI under test can be accessed using the following:</p> |
| |
| <pre> PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()</pre> |
| |
| <h3>Extending the GUI class under test to access protected methods</h3> |
| |
| <p><img src="images/tip.gif" alt=""> This is a simple |
| technique to allow your test to gain access to protected methods in the |
| class under test or one of it's super classes. In the example the local |
| class MyPhoneBookEntryEditorDialog extends the class under test |
| PhoneBookEntryEditorDialog so that the tests can access the, |
| getButton(int id), buttonPressed() and cancellPressed() methods these |
| methods can then be used in the tests.</p> |
| |
| <pre>class MyPhoneBookEntryEditorDialog extends PhoneBookEntryEditorDialog { |
| |
| public MyPhoneBookEntryEditorDialog(Shell parent, PhoneBookEntry phoneBookEntry) { |
| super(parent, phoneBookEntry); |
| } |
| |
| @Override |
| protected void buttonPressed(int buttonId) { |
| super.buttonPressed(buttonId); |
| } |
| |
| @Override |
| protected void cancelPressed() { |
| super.cancelPressed(); |
| } |
| |
| @Override |
| protected Button getButton(int id) { |
| return super.getButton(id); |
| } |
| }</pre> |
| |
| <h3>Making GUI Classes testable using package protection</h3> |
| |
| <p>Making the local variables package protected allows the unit |
| tests to access the GUI components during the rest run (see the <a |
| href="article.html#Making_GUI_Classes_testable_using">earlier |
| section</a> for further details).</p> |
| |
| <h2>Acknowledgements</h2> |
| |
| <p>This technique for automating PDE unit tests was first developed |
| by David Bosschaert at IONA Technologies.</p> |
| |
| <p>I'd like to thank Edwin Dankert and Sean Boylan, both of Duolog |
| Technologies who helped refine the technique and the article. |
| I'd also like to thank the reviewers Edwin Dankert, David |
| Bosschaert, Andrew Niefer of IBM and Wayne Beaton of Eclipse |
| for taking the time to read the article and provide all the excellent |
| feedback.</p> |
| </div> |
| |
| <div class="notices"> |
| <h3>Legal Notices</h3> |
| <p>Java and all Java-based trademarks and logos are trademarks or |
| registered trademarks of Sun Microsystems, Inc. in the United States, |
| other countries, or both.</p> |
| </div> |
| </body> |
| </html> |